Add api from tizen 2.3 11/33311/4
authorSangyoon Jang <s89.jang@samsung.com>
Thu, 8 Jan 2015 08:29:27 +0000 (17:29 +0900)
committerBaptiste DURAND <baptiste.durand@gmail.com>
Thu, 8 Jan 2015 14:37:16 +0000 (15:37 +0100)
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 <s89.jang@samsung.com>
Signed-off-by: Baptiste DURAND <baptiste.durand@open.eurogiciel.org>
client/include/package-manager.h
client/src/pkgmgr.c
comm/comm_config.h
packaging/pkgmgr.spec
server/src/pkgmgr-server.c
tool/CMakeLists.txt
tool/pkg_clearcache.c [new file with mode: 0644]

index f36fb8f..fcd590f 100644 (file)
@@ -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
index ea70fba..ae1f5d1 100644 (file)
@@ -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)
index 50ef0df..484760d 100644 (file)
@@ -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
 };
 
index 61e4711..d3c6886 100644 (file)
@@ -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}
index 8e2d50d..9285912 100644 (file)
@@ -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");
index 293adbf..216f541 100644 (file)
@@ -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 (file)
index 0000000..db98be2
--- /dev/null
@@ -0,0 +1,219 @@
+/*
+ * slp-pkgmgr
+ *
+ * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
+ *
+ * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>,
+ * Jaeho Lee <jaeho81.lee@samsung.com>, Shobhit Srivastava <shobhit.s@samsung.com>
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <dirent.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+#include <dlog.h>
+#include <tzplatform_config.h>
+#include <pkgmgr-info.h>
+#include <package-manager.h>
+
+#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;
+}