From e701f22a1220767cafd1ecfcb73179cecc9cf74b Mon Sep 17 00:00:00 2001 From: Sangyoon Jang Date: Thu, 8 Jan 2015 17:29:27 +0900 Subject: [PATCH] Add api from tizen 2.3 TC-2313 added: pkgmgr_client_request_size_info pkgmgr_client_clear_cache_dir pkgmgr_client_clear_all_cache_dir pkgmgr_client_get_package_size_info pkgmgr_client_get_total_package_size_info and also support multi-user Change-Id: I19ad887d6e231b266c0ab18e1b73ffc3f7b9686c Signed-off-by: Sangyoon Jang Signed-off-by: Baptiste DURAND --- client/include/package-manager.h | 96 +++++++++- client/src/pkgmgr.c | 376 ++++++++++++++++++++++++++++++++++++++- comm/comm_config.h | 4 + packaging/pkgmgr.spec | 1 + server/src/pkgmgr-server.c | 18 ++ tool/CMakeLists.txt | 4 + tool/pkg_clearcache.c | 219 +++++++++++++++++++++++ 7 files changed, 710 insertions(+), 8 deletions(-) create mode 100644 tool/pkg_clearcache.c diff --git a/client/include/package-manager.h b/client/include/package-manager.h index f36fb8f..fcd590f 100644 --- a/client/include/package-manager.h +++ b/client/include/package-manager.h @@ -109,6 +109,7 @@ extern "C" { #define PKGMGR_CLIENT_STATUS_MOVE 0x08 #define PKGMGR_CLIENT_STATUS_CLEAR_DATA 0x10 #define PKGMGR_CLIENT_STATUS_INSTALL_PROGRESS 0x20 +#define PKGMGR_CLIENT_STATUS_GET_SIZE 0x40 /** @} */ /* 1 -100 : Package command errors */ @@ -160,10 +161,17 @@ extern "C" { #define PKGCMD_ERR_ARGUMENT_INVALID_STR "ARGUMENT_INVALID" #define PKGCMD_ERR_UNKNOWN_STR "Unknown Error" +#define PKG_SIZE_INFO_TOTAL "__TOTAL__" +#define PKG_CLEAR_ALL_CACHE "__ALL__" /** * @brief Return values in pkgmgr. */ typedef enum _pkgmgr_return_val { + PKGMGR_R_ESYSTEM = -9, /**< Severe system error */ + PKGMGR_R_EIO = -8, /**< IO error */ + PKGMGR_R_ENOMEM = -7, /**< Out of memory */ + PKGMGR_R_ENOPKG = -6, /**< No such package */ + PKGMGR_R_EPRIV = -5, /**< Privilege denied */ PKGMGR_R_ETIMEOUT = -4, /**< Timeout */ PKGMGR_R_EINVAL = -3, /**< Invalid argument */ PKGMGR_R_ECOMM = -2, /**< Comunication Error */ @@ -193,6 +201,18 @@ typedef void* pkgmgr_pkginfo_h; typedef void* pkgmgr_appinfo_h; typedef void* pkgmgr_certinfo_h; +typedef void pkgmgr_client; +typedef void pkgmgr_info; + +typedef struct { + long long data_size; + long long cache_size; + long long app_size; + long long ext_data_size; + long long ext_cache_size; + long long ext_app_size; +} pkg_size_info_t; + typedef int (*pkgmgr_iter_fn)(const char* pkg_type, const char* pkgid, const char* version, void *data); @@ -209,6 +229,11 @@ typedef int (*pkgmgr_info_app_list_cb ) (const pkgmgr_appinfo_h handle, typedef int (*pkgmgr_info_app_category_list_cb ) (const char *category_name, void *user_data); +typedef void (*pkgmgr_pkg_size_info_receive_cb)(pkgmgr_client *pc, const char *pkgid, + const pkg_size_info_t *size_info, void *user_data); + +typedef void (*pkgmgr_total_pkg_size_info_receive_cb)(pkgmgr_client *pc, + const pkg_size_info_t *size_info, void *user_data); typedef void pkgmgr_client; @@ -275,11 +300,16 @@ typedef enum { }pkgmgr_request_service_type; typedef enum { - PM_GET_TOTAL_SIZE= 0, + PM_GET_TOTAL_SIZE = 0, PM_GET_DATA_SIZE = 1, PM_GET_ALL_PKGS = 2, + PM_GET_SIZE_INFO = 3, + PM_GET_TOTAL_AND_DATA = 4, + PM_GET_SIZE_FILE = 5, + PM_GET_PKG_SIZE_INFO = 6, + PM_GET_TOTAL_PKG_SIZE_INFO = 7, PM_GET_MAX -}pkgmgr_getsize_type; +} pkgmgr_getsize_type; /** * @brief This API creates pkgmgr client. @@ -621,6 +651,68 @@ int pkgmgr_client_get_size(pkgmgr_client * pc, const char *pkgid, pkgmgr_getsize int pkgmgr_client_usr_get_size(pkgmgr_client * pc, const char *pkgid, pkgmgr_getsize_type get_type, pkgmgr_handler event_cb, void *data, uid_t uid); /** + * @brief Gets the package size information. + * @details The package size info is asynchronously obtained by the specified callback function. + * + * @param[in] pc The pointer to pkgmgr_client instance + * @param[in] pkgid The package ID + * @param[in] result_cb The asynchronous callback function to get the package size information + * @param[in] user_data User data to be passed to the callback function + * + * @return 0 on success, otherwise a negative error value + * @retval #PKGMGR_R_OK Successful + * @retval #PKGMGR_R_EINVAL Invalid parameter + * @retval #PKGMGR_R_ERROR Internal error + */ +int pkgmgr_client_get_package_size_info(pkgmgr_client *pc, const char *pkgid, pkgmgr_pkg_size_info_receive_cb result_cb, void *user_data); +int pkgmgr_client_usr_get_package_size_info(pkgmgr_client *pc, const char *pkgid, pkgmgr_pkg_size_info_receive_cb result_cb, void *user_data, uid_t uid); + +/** + * @brief Gets the sum of the entire package size information. + * @details The package size info is asynchronously obtained by the specified callback function. + * + * @param[in] pc The pointer to pkgmgr_client instance + * @param[in] result_cb The asynchronous callback function to get the total package size information + * @param[in] user_data User data to be passed to the callback function + * + * @return 0 on success, otherwise a negative error value + * @retval #PKGMGR_R_OK Successful + * @retval #PKGMGR_R_EINVAL Invalid parameter + * @retval #PKGMGR_R_ERROR Internal error + */ +int pkgmgr_client_get_total_package_size_info(pkgmgr_client *pc, pkgmgr_total_pkg_size_info_receive_cb result_cb, void *user_data); +int pkgmgr_client_usr_get_total_package_size_info(pkgmgr_client *pc, pkgmgr_total_pkg_size_info_receive_cb result_cb, void *user_data, uid_t uid); + +/** + * @brief This API removes cache directories + * + * This API is for package-manager client application.\n + * + * @param[in] pkgid package id + * @return 0 if success, error code(<0) if fail\n + * @retval PKGMGR_R_OK success + * @retval PKGMGR_R_EINVAL invalid argument + * @retval PKGMGR_R_EPRIV privilege denied + * @retval PKGMGR_R_ERROR internal error +*/ +int pkgmgr_client_clear_cache_dir(const char *pkgid); +int pkgmgr_client_usr_clear_cache_dir(const char *pkgid, uid_t uid); + +/** + * @brief This API removes all cache directories + * + * This API is for package-manager client application.\n + * + * @return 0 if success, error code(<0) if fail\n + * @retval PKGMGR_R_OK success + * @retval PKGMGR_R_EINVAL invalid argument + * @retval PKGMGR_R_EPRIV privilege denied + * @retval PKGMGR_R_ERROR internal error +*/ +int pkgmgr_client_clear_all_cache_dir(void); +int pkgmgr_client_usr_clear_all_cache_dir(uid_t uid); + +/** * @brief This API provides package list * * This API is for package-manager client application.\n diff --git a/client/src/pkgmgr.c b/client/src/pkgmgr.c index ea70fba..ae1f5d1 100644 --- a/client/src/pkgmgr.c +++ b/client/src/pkgmgr.c @@ -93,6 +93,7 @@ typedef struct _pkgmgr_client_t { DBusConnection *bc; } broadcast; } info; + void *new_event_cb; } pkgmgr_client_t; typedef struct _iter_data { @@ -228,7 +229,7 @@ static void __error_to_string(int errnumber, char **errstr) } static void __add_op_cbinfo(pkgmgr_client_t * pc, int request_id, - const char *req_key, pkgmgr_handler event_cb, + const char *req_key, pkgmgr_handler event_cb, void *new_event_cb, void *data) { req_cb_info *cb_info; @@ -245,6 +246,7 @@ static void __add_op_cbinfo(pkgmgr_client_t * pc, int request_id, cb_info->event_cb = event_cb; cb_info->data = data; cb_info->next = NULL; + pc->new_event_cb = new_event_cb; if (pc->info.request.rhead == NULL) pc->info.request.rhead = cb_info; @@ -1029,6 +1031,221 @@ catch: } +static int __request_size_info(pkgmgr_client *pc, uid_t uid) +{ + char *req_key = NULL; + int ret =0; + char *pkgtype = "getsize"; + char *pkgid = "size_info"; + pkgmgr_getsize_type get_type = PM_GET_SIZE_INFO; + + char *argv[PKG_ARGC_MAX] = { NULL, }; + char *args = NULL; + int argcnt = 0; + int len = 0; + char *temp = NULL; + int i = 0; + char buf[128] = {'\0'}; + char *cookie = NULL; + + pkgmgr_client_t *mpc = (pkgmgr_client_t *) pc; + retvm_if(mpc->ctype != PC_REQUEST, PKGMGR_R_EINVAL, "mpc->ctype is not PC_REQUEST\n"); + + req_key = __get_req_key(pkgid); + + snprintf(buf, 128, "%d", get_type); + argv[argcnt++] = strdup(pkgid); + argv[argcnt++] = strdup(buf); + argv[argcnt++] = strdup(buf); + + /*** add quote in all string for special charactor like '\n'*** FIX */ + for (i = 0; i < argcnt; i++) { + temp = g_shell_quote(argv[i]); + len += (strlen(temp) + 1); + g_free(temp); + } + + args = (char *)calloc(len, sizeof(char)); + tryvm_if(args == NULL, ret = PKGMGR_R_EINVAL, "installer_path fail"); + + strncpy(args, argv[0], len - 1); + + for (i = 1; i < argcnt; i++) { + strncat(args, " ", strlen(" ")); + temp = g_shell_quote(argv[i]); + strncat(args, temp, strlen(temp)); + g_free(temp); + } + DBG("[args] %s [len] %d\n", args, len); + + /* get cookie from security-server */ + cookie = __get_cookie_from_security_server(); + tryvm_if(cookie == NULL, ret = PKGMGR_R_ERROR, "__get_cookie_from_security_server is NULL"); + + /* request */ + ret = comm_client_request(mpc->info.request.cc, req_key, COMM_REQ_GET_SIZE, pkgtype, pkgid, args, cookie, uid, 1); + if (ret < 0) { + ERR("COMM_REQ_GET_SIZE failed, ret=%d\n", ret); + } + +catch: + for (i = 0; i < argcnt; i++) + free(argv[i]); + + if(args) + free(args); + if (cookie) + free(cookie); + + return ret; +} + +static int __change_op_cb_for_getsize(pkgmgr_client *pc) +{ + int ret = -1; + + retvm_if(pc == NULL, PKGMGR_R_EINVAL, "package manager client pc is NULL"); + pkgmgr_client_t *mpc = (pkgmgr_client_t *) pc; + + /* free listening head */ + req_cb_info *tmp = NULL; + req_cb_info *prev = NULL; + for (tmp = mpc->info.request.rhead; tmp;) { + prev = tmp; + tmp = tmp->next; + free(prev); + } + + /* free dbus connection */ + ret = comm_client_free(mpc->info.request.cc); + retvm_if(ret < 0, PKGMGR_R_ERROR, "comm_client_free() failed - %d", ret); + + /* Manage pc for seperated event */ + mpc->ctype = PC_REQUEST; + mpc->status_type = PKGMGR_CLIENT_STATUS_GET_SIZE; + + + mpc->info.request.cc = comm_client_new(); + retvm_if(mpc->info.request.cc == NULL, PKGMGR_R_ERROR, "client creation failed"); + + ret = comm_client_set_status_callback(COMM_STATUS_BROADCAST_GET_SIZE, mpc->info.request.cc, __operation_callback, pc); + retvm_if(ret < 0, PKGMGR_R_ERROR, "set_status_callback() failed - %d", ret); + + return PKGMGR_R_OK; +} + +static int __get_package_size_info(pkgmgr_client_t *mpc, char *req_key, const char *pkgid, pkgmgr_getsize_type get_type, uid_t uid) +{ + char *argv[PKG_ARGC_MAX] = { NULL, }; + char *args = NULL; + int argcnt = 0; + char *pkgtype = "getsize"; //unused + char buf[128] = { 0, }; + int len = 0; + char *cookie = NULL; + char *temp = NULL; + int i = 0; + int ret = 0; + + snprintf(buf, 128, "%d", get_type); + argv[argcnt++] = strdup(pkgid); + argv[argcnt++] = strdup(buf); + argv[argcnt++] = strdup("-k"); + argv[argcnt++] = req_key; + + /*** add quote in all string for special charactor like '\n'*** FIX */ + for (i = 0; i < argcnt; i++) { + temp = g_shell_quote(argv[i]); + len += (strlen(temp) + 1); + g_free(temp); + } + + args = (char *)calloc(len, sizeof(char)); + tryvm_if(args == NULL, ret = PKGMGR_R_EINVAL, "installer_path fail"); + + strncpy(args, argv[0], len - 1); + + for (i = 1; i < argcnt; i++) { + strncat(args, " ", strlen(" ")); + temp = g_shell_quote(argv[i]); + strncat(args, temp, strlen(temp)); + g_free(temp); + } + DBG("[args] %s [len] %d\n", args, len); + + /* get cookie from security-server */ + cookie = __get_cookie_from_security_server(); + tryvm_if(cookie == NULL, ret = PKGMGR_R_ERROR, "__get_cookie_from_security_server is NULL"); + + /* request */ + ret = comm_client_request(mpc->info.request.cc, req_key, COMM_REQ_GET_SIZE, pkgtype, pkgid, args, cookie, uid, 1); + if (ret < 0) + ERR("COMM_REQ_GET_SIZE failed, ret=%d\n", ret); + +catch: + for (i = 0; i < argcnt; i++) + free(argv[i]); + + if(args) + free(args); + if (cookie) + free(cookie); + + return ret; +} + +static int __get_pkg_size_info_cb(int req_id, const char *req_type, + const char *pkgid, const char *key, + const char *value, const void *pc, void *user_data) +{ + int ret = 0; + DBG("reqid: %d, req type: %s, pkgid: %s, unused key: %s, size info: %s", + req_id, req_type, pkgid, key, value); + + pkg_size_info_t *size_info = (pkg_size_info_t *)malloc(sizeof(pkg_size_info_t)); + retvm_if(size_info == NULL, -1, "The memory is insufficient."); + + char *save_ptr = NULL; + char *token = strtok_r((char*)value, ":", &save_ptr); + size_info->data_size = atoll(token); + token = strtok_r(NULL, ":", &save_ptr); + size_info->cache_size = atoll(token); + token = strtok_r(NULL, ":", &save_ptr); + size_info->app_size = atoll(token); + token = strtok_r(NULL, ":", &save_ptr); + size_info->ext_data_size = atoll(token); + token = strtok_r(NULL, ":", &save_ptr); + size_info->ext_cache_size = atoll(token); + token = strtok_r(NULL, ":", &save_ptr); + size_info->ext_app_size = atoll(token); + + DBG("data: %lld, cache: %lld, app: %lld, ext_data: %lld, ext_cache: %lld, ext_app: %lld", + size_info->data_size, size_info->cache_size, size_info->app_size, + size_info->ext_data_size, size_info->ext_cache_size, size_info->ext_app_size); + + pkgmgr_client_t *pmc = (pkgmgr_client_t *)pc; + tryvm_if(pmc == NULL, ret = -1, "pkgmgr_client instance is null."); + + if (strcmp(pkgid, PKG_SIZE_INFO_TOTAL) == 0) + { // total package size info + pkgmgr_total_pkg_size_info_receive_cb callback = (pkgmgr_total_pkg_size_info_receive_cb)(pmc->new_event_cb); + callback((pkgmgr_client *)pc, size_info, user_data); + } + else + { + pkgmgr_pkg_size_info_receive_cb callback = (pkgmgr_pkg_size_info_receive_cb)(pmc->new_event_cb); + callback((pkgmgr_client *)pc, pkgid, size_info, user_data); + } + +catch: + + if(size_info){ + free(size_info); + size_info = NULL; + } + return ret; +} + API pkgmgr_client *pkgmgr_client_new(client_type ctype) { pkgmgr_client_t *pc = NULL; @@ -1180,7 +1397,7 @@ API int pkgmgr_client_usr_install(pkgmgr_client * pc, const char *pkg_type, /* 4. add callback info - add callback info to pkgmgr_client */ req_id = _get_request_id(); - __add_op_cbinfo(mpc, req_id, req_key, event_cb, data); + __add_op_cbinfo(mpc, req_id, req_key, event_cb, NULL, data); /* 5. generate argv */ @@ -1321,7 +1538,7 @@ API int pkgmgr_client_usr_reinstall(pkgmgr_client * pc, const char *pkg_type, co /* 4. add callback info - add callback info to pkgmgr_client */ req_id = _get_request_id(); - __add_op_cbinfo(mpc, req_id, req_key, event_cb, data); + __add_op_cbinfo(mpc, req_id, req_key, event_cb, NULL, data); /* 5. generate argv */ @@ -1477,7 +1694,7 @@ API int pkgmgr_client_usr_uninstall(pkgmgr_client *pc, const char *pkg_type, /* 4. add callback info - add callback info to pkgmgr_client */ req_id = _get_request_id(); - __add_op_cbinfo(mpc, req_id, req_key, event_cb, data); + __add_op_cbinfo(mpc, req_id, req_key, event_cb, NULL, data); /* 5. generate argv */ @@ -1754,7 +1971,7 @@ API int pkgmgr_client_move_usr_pkg(pkgmgr_client *pc, const char *pkg_type, /* 4. add callback info - add callback info to pkgmgr_client */ req_id = _get_request_id(); - __add_op_cbinfo(mpc, req_id, req_key, event_cb, data); + __add_op_cbinfo(mpc, req_id, req_key, event_cb, NULL, data); /* 5. generate argv */ snprintf(buf, 128, "%d", move_type); @@ -2399,6 +2616,97 @@ catch: } +API int pkgmgr_client_usr_request_size_info(uid_t uid) +{ + int ret = 0; + pkgmgr_client *pc = NULL; + + pc = pkgmgr_client_new(PC_REQUEST); + retvm_if(pc == NULL, PKGMGR_R_EINVAL, "request pc is null\n"); + + ret = __request_size_info(pc, uid); + if (ret < 0) { + ERR("__request_size_info fail \n"); + } + + pkgmgr_client_free(pc); + return ret; +} + +API int pkgmgr_client_request_size_info(void) // get all package size (data, total) +{ + return pkgmgr_client_usr_request_size_info(GLOBAL_USER); +} + +API int pkgmgr_client_usr_clear_cache_dir(const char *pkgid, uid_t uid) +{ + retvm_if(pkgid == NULL, PKGMGR_R_EINVAL, "package id is null\n"); + + int ret = 0; + pkgmgr_client_t *pc = NULL; + char *pkg_type = NULL; + char *cookie = NULL; + int is_type_malloced = 0; + + pkgmgrinfo_pkginfo_h handle = NULL; + + pc = pkgmgr_client_new(PC_REQUEST); + retvm_if(pc == NULL, PKGMGR_R_ESYSTEM, "request pc is null\n"); + + if (strcmp(pkgid, PKG_CLEAR_ALL_CACHE) != 0) + { + ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &handle); + tryvm_if(ret < 0, ret = PKGMGR_R_ENOPKG, "pkgmgr_pkginfo_get_pkginfo failed"); + + ret = pkgmgrinfo_pkginfo_get_type(handle, &pkg_type); + tryvm_if(ret < 0, ret = PKGMGR_R_ESYSTEM, "pkgmgr_pkginfo_get_type failed"); + } + else + { + pkg_type = (char *)malloc(strlen("rpm") + 1); + strcpy(pkg_type, "rpm"); + is_type_malloced = 1; + } + + cookie = __get_cookie_from_security_server(); + tryvm_if(cookie == NULL, ret = PKGMGR_R_ESYSTEM, "__get_cookie_from_security_server is NULL"); + + ret = comm_client_request(pc->info.request.cc, NULL, COMM_REQ_CLEAR_CACHE_DIR, pkg_type, pkgid, NULL, cookie, uid, 0); + tryvm_if(ret < 0, ret = PKGMGR_R_ERROR, "COMM_REQ_CLEAR_CACHE_DIR failed, ret=%d\n", ret); + + ret = PKGMGR_R_OK; +catch: + if (cookie) + free(cookie); + + if (pc) + pkgmgr_client_free(pc); + + if(is_type_malloced) + free(pkg_type); + + pkgmgrinfo_pkginfo_destroy_pkginfo(handle); + + return ret; +} + +API int pkgmgr_client_clear_cache_dir(const char *pkgid) +{ + return pkgmgr_client_usr_clear_cache_dir(pkgid, GLOBAL_USER); +} + +API int pkgmgr_client_clear_usr_all_cache_dir(uid_t uid) +{ + return pkgmgr_client_usr_clear_cache_dir(PKG_CLEAR_ALL_CACHE, uid); +} + +API int pkgmgr_client_clear_all_cache_dir(void) +{ + int ret = 0; + ret = pkgmgr_client_usr_clear_cache_dir(PKG_CLEAR_ALL_CACHE, GLOBAL_USER); + return ret; +} + API int pkgmgr_client_get_size(pkgmgr_client * pc, const char *pkgid, pkgmgr_getsize_type get_type, pkgmgr_handler event_cb, void *data) { return pkgmgr_client_usr_get_size(pc, pkgid, get_type, event_cb, data, GLOBAL_USER); @@ -2428,7 +2736,7 @@ API int pkgmgr_client_usr_get_size(pkgmgr_client * pc, const char *pkgid, pkgmgr retvm_if(req_key == NULL, PKGMGR_R_EINVAL, "req_key is NULL"); req_id = _get_request_id(); - __add_op_cbinfo(mpc, req_id, req_key, event_cb, data); + __add_op_cbinfo(mpc, req_id, req_key, event_cb, NULL, data); snprintf(buf, 128, "%d", get_type); argv[argcnt++] = strdup(pkgid); @@ -2477,6 +2785,62 @@ catch: return ret; } +API int pkgmgr_client_usr_get_package_size_info(pkgmgr_client *pc, const char *pkgid, pkgmgr_pkg_size_info_receive_cb event_cb, void *user_data, uid_t uid) +{ + pkgmgrinfo_pkginfo_h pkginfo = NULL; + char *req_key = NULL; + int req_id = 0; + int res = 0; + int type = PM_GET_PKG_SIZE_INFO; + + retvm_if(pc == NULL, PKGMGR_R_EINVAL, "The specified pc is NULL."); + retvm_if(pkgid == NULL, PKGMGR_R_EINVAL, "The package id is NULL."); + + if (strcmp(pkgid, PKG_SIZE_INFO_TOTAL) == 0) + { // total package size info + type = PM_GET_TOTAL_PKG_SIZE_INFO; + } + else + { + res = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &pkginfo); + retvm_if(res != 0, PKGMGR_R_ENOPKG, "The package id is not installed."); + + if (pkginfo) { + pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo); + } + } + + pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc; + retvm_if(mpc->ctype != PC_REQUEST, PKGMGR_R_EINVAL, "mpc->ctype is not PC_REQUEST"); + + res = __change_op_cb_for_getsize(mpc); + retvm_if(res < 0 , PKGMGR_R_ESYSTEM, "__change_op_cb_for_getsize is fail"); + + req_key = __get_req_key(pkgid); + retvm_if(req_key == NULL, PKGMGR_R_ESYSTEM, "req_key is NULL"); + + req_id = _get_request_id(); + __add_op_cbinfo(mpc, req_id, req_key, __get_pkg_size_info_cb, event_cb, user_data); + + res = __get_package_size_info(mpc, req_key, pkgid, type, uid); + + return res; +} + +API int pkgmgr_client_get_package_size_info(pkgmgr_client *pc, const char *pkgid, pkgmgr_pkg_size_info_receive_cb event_cb, void *user_data) +{ + return pkgmgr_client_usr_get_package_size_info(pc, pkgid, event_cb, user_data, GLOBAL_USER); +} + +API int pkgmgr_client_usr_get_total_package_size_info(pkgmgr_client *pc, pkgmgr_total_pkg_size_info_receive_cb event_cb, void *user_data, uid_t uid) +{ // total package size info + return pkgmgr_client_usr_get_package_size_info(pc, PKG_SIZE_INFO_TOTAL, (pkgmgr_pkg_size_info_receive_cb)event_cb, user_data, uid); +} + +API int pkgmgr_client_get_total_package_size_info(pkgmgr_client *pc, pkgmgr_total_pkg_size_info_receive_cb event_cb, void *user_data) +{ + return pkgmgr_client_usr_get_package_size_info(pc, PKG_SIZE_INFO_TOTAL, event_cb, user_data, GLOBAL_USER); +} #define __START_OF_OLD_API ail_cb_ret_e __appinfo_func(const ail_appinfo_h appinfo, void *user_data) diff --git a/comm/comm_config.h b/comm/comm_config.h index 50ef0df..484760d 100644 --- a/comm/comm_config.h +++ b/comm/comm_config.h @@ -104,6 +104,9 @@ enum { /*check app */ COMM_REQ_CHECK_APP, + /* to cache clear */ + COMM_REQ_CLEAR_CACHE_DIR, + COMM_REQ_MAX_SENTINEL }; @@ -125,6 +128,7 @@ enum { COMM_STATUS_BROADCAST_MOVE, COMM_STATUS_BROADCAST_INSTALL_PROGRESS, COMM_STATUS_BROADCAST_UPGRADE, + COMM_STATUS_BROADCAST_GET_SIZE, COMM_STATUS_BROADCAST_MAX }; diff --git a/packaging/pkgmgr.spec b/packaging/pkgmgr.spec index 61e4711..d3c6886 100644 --- a/packaging/pkgmgr.spec +++ b/packaging/pkgmgr.spec @@ -149,6 +149,7 @@ chsmack -a '*' %{TZ_SYS_RW_PACKAGES} %attr(06755,root,root) %{_bindir}/pkg_initdb %attr(755,root,root) %{_bindir}/pkg_initdb_user %{_bindir}/pkg_getsize +%{_bindir}/pkg_clearcache %{_bindir}/pkginfo %{_bindir}/pkgmgr-install %attr(-,tizenglobalapp,root) %dir %{TZ_SYS_RW_PACKAGES} diff --git a/server/src/pkgmgr-server.c b/server/src/pkgmgr-server.c index 8e2d50d..9285912 100644 --- a/server/src/pkgmgr-server.c +++ b/server/src/pkgmgr-server.c @@ -55,6 +55,7 @@ #include "pkgmgr-server.h" #include "pm-queue.h" #include "comm_config.h" +#include "package-manager.h" #define PACKAGE_RECOVERY_DIR tzplatform_mkpath(TZ_SYS_RW_PACKAGES, ".recovery/pkgmgr") #define NO_MATCHING_FILE 11 @@ -1034,6 +1035,23 @@ void req_cb(void *cb_data, uid_t uid, const char *req_id, const int req_type, queue_job(NULL); *ret = COMM_RET_OK; break; + case COMM_REQ_CLEAR_CACHE_DIR: + /* check caller privilege */ + cookie_result = __check_privilege_by_cookie(cookie, item->req_type); + if (cookie_result < 0){ + LOGE("__check_privilege_by_cookie result fail[%d]\n", cookie_result); + *ret = PKGMGR_R_EPRIV; + goto err; + } + + err = _pm_queue_push(item); + p = __get_position_from_pkg_type(item->pkg_type); + __set_backend_mode(p); + + if (err == 0) + g_idle_add(queue_job, NULL); + *ret = PKGMGR_R_OK; + break; default: DBG("Check your request..\n"); diff --git a/tool/CMakeLists.txt b/tool/CMakeLists.txt index 293adbf..216f541 100644 --- a/tool/CMakeLists.txt +++ b/tool/CMakeLists.txt @@ -60,6 +60,10 @@ add_executable(pkg_syncdb_user pkg_syncdb_user.c) target_link_libraries(pkg_syncdb_user ${pkgs_initdb_LDFLAGS}) INSTALL(TARGETS pkg_syncdb_user DESTINATION bin) +add_executable(pkg_clearcache pkg_clearcache.c) +target_link_libraries(pkg_clearcache ${pkgs_test_LDFLAGS}) +install(TARGETS pkg_clearcache DESTINATION bin) + add_executable(pkg_initdb pkg_initdb.c) target_link_libraries(pkg_initdb ${pkgs_initdb_LDFLAGS}) INSTALL(TARGETS pkg_initdb DESTINATION bin) diff --git a/tool/pkg_clearcache.c b/tool/pkg_clearcache.c new file mode 100644 index 0000000..db98be2 --- /dev/null +++ b/tool/pkg_clearcache.c @@ -0,0 +1,219 @@ +/* + * slp-pkgmgr + * + * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved. + * + * Contact: Jayoun Lee , Sewook Park , + * Jaeho Lee , Shobhit Srivastava + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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. + * + */ + +#define _GNU_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define MAX_PKG_NAME_LEN 256 +#define INTERNAL_CACHE_PATH_PREFIX tzplatform_getenv(TZ_USER_APP) +#define CACHE_PATH_POSTFIX "/cache" +#define SHARED_PATH_POSTFIX "/shared/cache" + + +#undef LOG_TAG +#ifndef LOG_TAG +#define LOG_TAG "PKGMGR_CLEARCACHE" +#endif /* LOG_TAG */ + +static int __clear_dir(const char *dirname) +{ + int ret = 0; + DIR *dp = NULL; + struct dirent *ep = NULL; + char *abs_filename = NULL; + struct stat stFileInfo; + + LOGD("Cache directory name to clear [%s]\n", dirname); + + abs_filename = (char *)malloc(sizeof(char) * PATH_MAX); + if (abs_filename == NULL) { + LOGE("Memory allocation failed\n"); + goto err; + } + + dp = opendir(dirname); + if (dp != NULL) { + while ((ep = readdir(dp))) { + snprintf(abs_filename, PATH_MAX - 1, "%s/%s", dirname, ep->d_name); + if (lstat(abs_filename, &stFileInfo) < 0) { + perror(abs_filename); + } + if (S_ISDIR(stFileInfo.st_mode)) { + if (strcmp(ep->d_name, ".") && strcmp(ep->d_name, "..")) { + ret = __clear_dir(abs_filename); + if (ret != 0) { + LOGE("Couldn't remove the directory. errno : %d (%s)\n", errno, strerror(errno)); + } + + ret = remove(abs_filename); + if (ret != 0) { + LOGE("Couldn't remove the directory. errno : %d (%s)\n", errno, strerror(errno)); + goto err; + } + } + } else { + ret = remove(abs_filename); + if (ret != 0) { + LOGE("Couldn't remove the directory. errno : %d (%s)\n", errno, strerror(errno)); + goto err; + } + } + } + (void)closedir(dp); + } else { + LOGE("Couldn't open the directory. errno : %d (%s)\n", errno, strerror(errno)); + goto err; + } + + free(abs_filename); + return 0; + +err: + if (abs_filename) { + free(abs_filename); + } + if(dp){ + (void)closedir(dp); + dp = NULL; + } + return -1; +} + +static int __clear_cache_dir(const char *pkgid) +{ + int ret = 0; + char dirname[PATH_MAX] = {0,}; + + if(pkgid == NULL) { + LOGE("pkgid is NULL\n"); + return -1; + } + + int internal_prefix_len = sizeof(INTERNAL_CACHE_PATH_PREFIX); + int cache_postfix_len = sizeof(CACHE_PATH_POSTFIX); + int shared_postfix_len = sizeof(SHARED_PATH_POSTFIX); + + // cache internal + strcat(dirname, INTERNAL_CACHE_PATH_PREFIX); + strncat(dirname, pkgid, PATH_MAX - internal_prefix_len - cache_postfix_len - 1); + strcat(dirname, CACHE_PATH_POSTFIX); + + ret = __clear_dir(dirname); + if (ret < 0) { + LOGE("Failed to clear internal cache dir."); + } + + // shared/cache internal + memset(dirname, 0x00, PATH_MAX); + strcat(dirname, INTERNAL_CACHE_PATH_PREFIX); + strncat(dirname, pkgid, PATH_MAX - internal_prefix_len - shared_postfix_len - 1); + strcat(dirname, SHARED_PATH_POSTFIX); + + ret = __clear_dir(dirname); + if (ret < 0) { + LOGE("Failed to clear external shared cache dir."); + } + + return 0; +} + +static int __clear_all_cache_dir_cb(const pkgmgrinfo_pkginfo_h handle, void *user_data) +{ + int res = 0; + char *pkgid; + int *err_cnt = (int *)user_data; + + res = pkgmgrinfo_pkginfo_get_pkgid(handle, &pkgid); + if(res != PMINFO_R_OK) { + LOGE("pkgmgr_pkginfo_get_pkgid() failed"); + --(*err_cnt); + return 0; + } + + res = __clear_cache_dir(pkgid); + if (res != 0) + { // error flag + LOGE("Failed to clear cache dir of %s", pkgid); + --(*err_cnt); + return 0; + } + + return 0; +} + +static int __clear_all_cache_dir(void) +{ + int err_cnt = 0; + + int res = pkgmgrinfo_pkginfo_get_usr_list(__clear_all_cache_dir_cb, &err_cnt, getuid()); + if (res != PMINFO_R_OK) + { + LOGE("Failed to get pkg list. (%d)", res); + return -1; + } + else if (err_cnt != 0) + { + LOGE("Error occured in %d packages.", err_cnt); + return -1; + } + + return 0; +} + +int main(int argc, char *argv[]) +{ + int ret = 0; + + if(argv[0] == NULL) { + LOGE("pkgid is NULL\n"); + return -1; + } + + char pkgid[MAX_PKG_NAME_LEN]={0}; + + snprintf(pkgid,MAX_PKG_NAME_LEN,"%s",argv[0]); + + if (strcmp(pkgid, PKG_CLEAR_ALL_CACHE) == 0) + { // clear all + ret = __clear_all_cache_dir(); + } + else + { + ret = __clear_cache_dir(pkgid); + } + + + return ret; +} -- 2.7.4