--- /dev/null
+/*
+ * 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.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <sys/inotify.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/xattr.h>
+#include <fcntl.h>
+#include <dirent.h>
+#include <ctype.h>
+#include <glib.h>
+#include <glib-object.h>
+#include <signal.h>
+#include <dbus/dbus.h>
+#include <security-server.h>
+#include <pkgmgr-info.h>
+#include <pkgmgr_parser.h>
+#include <pkgmgrinfo_zone.h>
+#include <vasum.h>
+#include <aul.h>
+#ifdef _APPFW_FEATURE_DRM_ENABLE
+#include <drm-tizen-apps.h>
+#endif
+
+#include "pm-queue.h"
+#include "pkgmgr-server.h"
+#include <package-manager.h>
+#include <package-manager-debug.h>
+#include <pkgmgr/pkgmgr_installer.h>
+#include <pkgmgr/comm_pkg_mgr_server.h>
+#include <pkgmgr/comm_config.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "PKGMGR_SERVER"
+
+#define IS_WHITESPACE(CHAR) \
+((CHAR == ' ' || CHAR == '\t' || CHAR == '\r' || CHAR == '\n') ? TRUE : FALSE)
+
+#define PACKAGE_RECOVERY_DIR "/opt/share/packages/.recovery/pkgmgr"
+#define ZONE_HOST "host"
+#define PKG_DATA_PATH "/opt/usr/data/pkgmgr"
+
+#define DESKTOP_W 720.0
+
+#define NO_MATCHING_FILE 11
+
+typedef struct checkapp_data {
+ char *sub_cmd;
+ char *zone_name;
+} checkapp_data_s;
+
+static int backend_flag = 0; /* 0 means that backend process is not running */
+
+/*
+8 bit value to represent maximum 8 backends.
+Each bit position corresponds to a queue slot which
+is dynamically determined.
+*/
+char backend_busy = 0;
+int drm_busy = 0;
+
+/*
+8 bit value to represent quiet mode operation for maximum 8 backends
+1->quiet 0->non-quiet
+Each bit position corresponds to a queue slot which
+is dynamically determined.
+*/
+char backend_mode = 63; /*00111111*/
+extern int num_of_backends;
+
+backend_info *begin;
+extern queue_info_map *start;
+extern int entries;
+int pos = 0;
+/*To store info in case of backend crash*/
+char pname[MAX_PKG_NAME_LEN] = {'\0'};
+char ptype[MAX_PKG_TYPE_LEN] = {'\0'};
+char args[MAX_PKG_ARGS_LEN] = {'\0'};
+
+GMainLoop *mainloop = NULL;
+
+static int __check_backend_status_for_exit();
+static int __check_queue_status_for_exit();
+static int __is_backend_busy(int position);
+static void __set_backend_busy(int position);
+static void __set_backend_free(int position);
+static void __set_backend_mode(int position);
+static void __unset_backend_mode(int position);
+
+static void sighandler(int signo);
+gboolean queue_job(void *data);
+gboolean send_fail_signal(void *data);
+gboolean exit_server(void *data);
+
+/* To check whether a particular backend is free/busy*/
+static int __is_backend_busy(int position)
+{
+ return backend_busy & 1<<position;
+}
+static void __set_drm_busy(int position)
+{
+ drm_busy = position;
+}
+/*To set a particular backend as busy*/
+static void __set_backend_busy(int position)
+{
+ backend_busy = backend_busy | 1<<position;
+}
+/*To set a particular backend as free */
+static void __set_backend_free(int position)
+{
+ backend_busy = backend_busy & ~(1<<position);
+}
+
+/*To set a particular backend mode as quiet*/
+static void __set_backend_mode(int position)
+{
+ backend_mode = backend_mode | 1<<position;
+}
+/*To unset a particular backend mode */
+static void __unset_backend_mode(int position)
+{
+ backend_mode = backend_mode & ~(1<<position);
+}
+
+static void __set_recovery_mode(char *pkgid, char *pkg_type, const char *zone)
+{
+ char recovery_file[MAX_PKG_NAME_LEN] = { 0, };
+ char buffer[MAX_PKG_NAME_LEN] = { 0 };
+ char temp_path[MAX_PKG_NAME_LEN] = { 0 };
+ char *pkgid_tmp = NULL;
+ FILE *rev_file = NULL;
+
+ if (pkgid == NULL) {
+ _LOGE("pkgid is null");
+ return;
+ }
+
+ if (zone && strlen(zone) && strcmp(zone, ZONE_HOST) != 0) {
+ char *rootpath = NULL;
+
+ rootpath = _zone_get_root_path(zone);
+ if (rootpath == NULL) {
+ _LOGE("rootpath is null");
+ return;
+ }
+ snprintf(temp_path, MAX_PKG_NAME_LEN, "%s%s", rootpath, PACKAGE_RECOVERY_DIR);
+ dbg("temp_path(%s)", temp_path);
+ } else {
+ snprintf(temp_path, MAX_PKG_NAME_LEN, "%s", PACKAGE_RECOVERY_DIR);
+ }
+
+ /*if pkgid has a "/"charactor, that is a path name for installation, then extract pkgid from absolute path*/
+ if (strstr(pkgid, "/")) {
+ pkgid_tmp = strrchr(pkgid, '/') + 1;
+ if (pkgid_tmp == NULL) {
+ _LOGE("pkgid_tmp[%s] is null", pkgid);
+ return;
+ }
+ snprintf(recovery_file, MAX_PKG_NAME_LEN, "%s/%s", temp_path, pkgid_tmp);
+ } else {
+ snprintf(recovery_file, MAX_PKG_NAME_LEN, "%s/%s", temp_path, pkgid);
+ }
+
+ rev_file = fopen(recovery_file, "w");
+ if (rev_file== NULL) {
+ _LOGE("rev_file[%s] is null", recovery_file);
+ return;
+ }
+
+ snprintf(buffer, MAX_PKG_NAME_LEN, "pkgid : %s\n", pkgid);
+ fwrite(buffer, sizeof(char), strlen(buffer), rev_file);
+
+ fclose(rev_file);
+}
+
+static void __unset_recovery_mode(char *pkgid, char *pkg_type, const char *zone)
+{
+ int ret = -1;
+ char recovery_file[MAX_PKG_NAME_LEN] = { 0, };
+ char temp_path[MAX_PKG_NAME_LEN] = { 0, };
+ char *pkgid_tmp = NULL;
+
+ if (pkgid == NULL) {
+ _LOGE("pkgid is null");
+ return;
+ }
+
+ if (zone && strlen(zone) && strcmp(zone, ZONE_HOST) != 0) {
+ char *rootpath = NULL;
+ rootpath = _zone_get_root_path(zone);
+ if (rootpath == NULL) {
+ _LOGE("rootpath is null");
+ return;
+ }
+ snprintf(temp_path, MAX_PKG_NAME_LEN, "%s%s", rootpath, PACKAGE_RECOVERY_DIR);
+ } else {
+ snprintf(temp_path, MAX_PKG_NAME_LEN, "%s", PACKAGE_RECOVERY_DIR);
+ }
+
+ /*if pkgid has a "/"charactor, that is a path name for installation, then extract pkgid from absolute path*/
+ if (strstr(pkgid, "/")) {
+ pkgid_tmp = strrchr(pkgid, '/') + 1;
+ if (pkgid_tmp == NULL) {
+ _LOGE("pkgid_tmp[%s] is null", pkgid);
+ return;
+ }
+ snprintf(recovery_file, MAX_PKG_NAME_LEN, "%s/%s", temp_path, pkgid_tmp);
+ } else {
+ snprintf(recovery_file, MAX_PKG_NAME_LEN, "%s/%s", temp_path, pkgid);
+ }
+
+ ret = remove(recovery_file);
+ if (ret < 0)
+ _LOGE("remove recovery_file[%s] fail", recovery_file);
+}
+
+static int __check_privilege_by_cookie(const char *e_cookie, int req_type)
+{
+ guchar *cookie = NULL;
+ gsize size;
+ int ret = PMINFO_R_ERROR;
+
+ if (e_cookie == NULL) {
+ _LOGE("e_cookie is NULL!!!");
+ return PMINFO_R_ERROR;
+ }
+
+ cookie = g_base64_decode(e_cookie, &size);
+ if (cookie == NULL) {
+ _LOGE("Unable to decode cookie!!!");
+ return PMINFO_R_ERROR;
+ }
+
+ switch (req_type) {
+ case COMM_REQ_TO_INSTALL:
+ case COMM_REQ_TO_UNINSTALL:
+ ret = security_server_check_privilege_by_cookie((const char*)cookie, "pkgmgr::svc", "r");
+ if (SECURITY_SERVER_API_SUCCESS == ret)
+ ret = PMINFO_R_OK;
+ break;
+
+ case COMM_REQ_TO_MOVER:
+ ret = security_server_check_privilege_by_cookie((const char*)cookie, "pkgmgr::svc", "x");
+ if (SECURITY_SERVER_API_SUCCESS == ret)
+ ret = PMINFO_R_OK;
+ break;
+
+ case COMM_REQ_GET_SIZE:
+ ret = security_server_check_privilege_by_cookie((const char*)cookie, "pkgmgr::info", "r");
+ if (SECURITY_SERVER_API_SUCCESS == ret)
+ ret = PMINFO_R_OK;
+ break;
+
+ case COMM_REQ_CLEAR_CACHE_DIR:
+ ret = security_server_check_privilege_by_cookie((const char*)cookie, "pkgmgr::cache", "w");
+ if (SECURITY_SERVER_API_SUCCESS == ret)
+ ret = PMINFO_R_OK;
+ break;
+
+ default:
+ _LOGE("Check your request[%d]..", req_type);
+ break;
+ }
+
+ _LOGD("security_server[req-type:%d] check cookie result = %d", req_type, ret);
+
+ if (cookie){
+ g_free(cookie);
+ cookie = NULL;
+ }
+
+ return ret;
+}
+
+static int __check_admin_privilege_by_cookie(const char *e_cookie)
+{
+ guchar *cookie = NULL;
+ gsize size;
+ int ret = PMINFO_R_ERROR;
+
+ if (e_cookie == NULL) {
+ _LOGE("e_cookie is NULL!!!");
+ return PMINFO_R_ERROR;
+ }
+
+ cookie = g_base64_decode(e_cookie, &size);
+ if (cookie == NULL) {
+ _LOGE("Unable to decode cookie!!!");
+ return PMINFO_R_ERROR;
+ }
+
+ ret = security_server_check_privilege_by_cookie((const char *)cookie, "privilege::tizen::packagemanager.admin rw", "rw");
+ if (ret == SECURITY_SERVER_API_SUCCESS)
+ ret = PMINFO_R_OK;
+
+
+ if (cookie){
+ g_free(cookie);
+ cookie = NULL;
+ }
+
+ return ret;
+}
+
+
+static int __get_position_from_pkg_type(char *pkgtype)
+{
+ int i = 0;
+ queue_info_map *ptr;
+ ptr = start;
+ for(i = 0; i < entries; i++)
+ {
+ if (!strncmp(ptr->pkgtype, pkgtype, MAX_PKG_TYPE_LEN))
+ return ptr->queue_slot;
+ else
+ ptr++;
+
+ }
+ return -1;
+}
+
+gboolean send_fail_signal(void *data)
+{
+ _LOGD("send_fail_signal start");
+ gboolean ret_parse;
+ gint argcp;
+ gchar **argvp;
+ GError *gerr = NULL;
+ pkgmgr_installer *pi;
+ pi = pkgmgr_installer_new();
+ if (!pi) {
+ _LOGE("Failure in creating the pkgmgr_installer object");
+ return FALSE;
+ }
+ ret_parse = g_shell_parse_argv(args,
+ &argcp, &argvp, &gerr);
+ if (FALSE == ret_parse) {
+ _LOGE("Failed to split args: %s", args);
+ _LOGE("messsage: %s", gerr->message);
+ pkgmgr_installer_free(pi);
+ return FALSE;
+ }
+
+ pkgmgr_installer_receive_request(pi, argcp, argvp);
+ pkgmgr_installer_send_signal(pi, ptype, pname, "end", "fail");
+ pkgmgr_installer_free(pi);
+ return FALSE;
+}
+
+static void sighandler(int signo)
+{
+ int status;
+ pid_t cpid;
+ int i = 0;
+ backend_info *ptr = NULL;
+ ptr = begin;
+
+ while ((cpid = waitpid(-1, &status, WNOHANG)) > 0) {
+ _LOGD("child exit [%d]", cpid);
+ if (WIFEXITED(status)) {
+ for(i = 0; i < num_of_backends; i++)
+ {
+ if (cpid == (ptr + i)->pid) {
+ __set_backend_free(i);
+ __set_backend_mode(i);
+ __unset_recovery_mode((ptr + i)->pkgid, (ptr + i)->pkgtype, (ptr + i)->zone);
+ if (WEXITSTATUS(status)) {
+ strncpy(pname, (ptr + i)->pkgid, MAX_PKG_NAME_LEN-1);
+ strncpy(ptype, (ptr + i)->pkgtype, MAX_PKG_TYPE_LEN-1);
+ strncpy(args, (ptr + i)->args, MAX_PKG_ARGS_LEN-1);
+ g_idle_add(send_fail_signal, NULL);
+ _LOGE("child exit [%d] with error code:%d", cpid, WEXITSTATUS(status));
+ } else {
+ _LOGE("child NORMAL exit [%d]", cpid);
+ }
+ break;
+ }
+ }
+ }
+ else if (WIFSIGNALED(status)) {
+ _LOGE("child SIGNALED exit [%d]", cpid);
+ /*get the pkgid and pkgtype to send fail signal*/
+ for(i = 0; i < num_of_backends; i++)
+ {
+ if (cpid == (ptr + i)->pid) {
+ __set_backend_free(i);
+ __set_backend_mode(i);
+ __unset_recovery_mode((ptr + i)->pkgid, (ptr + i)->pkgtype, (ptr + i)->zone);
+ strncpy(pname, (ptr + i)->pkgid, MAX_PKG_NAME_LEN-1);
+ strncpy(ptype, (ptr + i)->pkgtype, MAX_PKG_TYPE_LEN-1);
+ strncpy(args, (ptr + i)->args, MAX_PKG_ARGS_LEN-1);
+ g_idle_add(send_fail_signal, NULL);
+ break;
+ }
+ }
+ }
+ }
+
+}
+
+static void __register_signal_handler(void)
+{
+ static int sig_reg = 0;
+
+ if (sig_reg == 0) {
+ struct sigaction act;
+
+ act.sa_handler = sighandler;
+ sigemptyset(&act.sa_mask);
+ act.sa_flags = SA_NOCLDSTOP;
+
+ if (sigaction(SIGCHLD, &act, NULL) < 0) {
+ _LOGE("signal: SIGCHLD failed");
+ }
+ if (!g_timeout_add_seconds(2, exit_server, NULL)) {
+ _LOGE("Add g_timeout_add_seconds() to Main Loop is failed.");
+ }
+
+ sig_reg = 1;
+ }
+}
+
+#ifdef _APPFW_FEATURE_DRM_ENABLE
+int decrypt_pkg_cb(const char *drm_file_path, const char *decrypted_file_path, const char *cookie, int *ret)
+{
+ __register_signal_handler();
+
+ _LOGE(">> in callback >> package_manager_drm_decrypt_license is called.");
+
+ if (drm_file_path == NULL || decrypted_file_path == NULL || cookie == NULL) {
+ _LOGE("Invalid parameter.");
+ *ret = PKGMGR_R_EINVAL;
+ __set_drm_busy(0);
+ return -1;
+ }
+ int retval = 0;
+ const char *smack_label = "*";
+ int cookie_result = 0;
+
+ cookie_result = __check_admin_privilege_by_cookie(cookie);
+ if (cookie_result < 0){
+ _LOGE("__check_admin_privilege_by_cookie result fail[%d]", cookie_result);
+ *ret = PKGMGR_R_EPRIV;
+ return -1;
+ }
+
+ retval = drm_tizen_decrypt_package(drm_file_path, strlen(drm_file_path), decrypted_file_path, strlen(decrypted_file_path));
+ if (retval != 1) {
+ _LOGE("drm_tizen_decrypt_package is failed.");
+ *ret = PKGMGR_R_ERROR;
+ __set_drm_busy(0);
+ return -1;
+ }
+
+ if (security_server_label_access(decrypted_file_path, smack_label) != 0) {
+ _LOGE("error(%d) in setting smack label.", errno);
+ } else {
+ _LOGD("security_server_label_access(%s, %s) is ok.", decrypted_file_path, smack_label);
+ }
+
+ _LOGD("[%s] smack label is changed.", decrypted_file_path);
+
+ _LOGD("package_manager_drm_decrypt_package is successful.");
+ *ret = PKGMGR_R_OK;
+ __set_drm_busy(0);
+
+ return 0;
+}
+
+int reg_license_cb(const char *resp_data, const char *cookie, int *ret)
+{
+ __register_signal_handler();
+
+ _LOGE(">> in callback >> package_manager_drm_register_license is called.");
+
+ if (resp_data == NULL || cookie == NULL) {
+ _LOGE("Invalid parameter.");
+ *ret = PKGMGR_R_EINVAL;
+ __set_drm_busy(0);
+ return -1;
+ }
+ int retval = 0;
+ int cookie_result = 0;
+
+ cookie_result = __check_admin_privilege_by_cookie(cookie);
+ if (cookie_result < 0){
+ _LOGE("__check_admin_privilege_by_cookie result fail[%d]", cookie_result);
+ *ret = PKGMGR_R_EPRIV;
+ return -1;
+ }
+
+ retval = drm_tizen_register_license(resp_data, strlen(resp_data));
+ if (retval != 1) {
+ _LOGE("drm_tizen_register_license is failed.");
+ *ret = PKGMGR_R_ERROR;
+ __set_drm_busy(0);
+ return -1;
+ }
+
+ _LOGE("package_manager_drm_register_license is successful.");
+ *ret = PKGMGR_R_OK;
+
+ return 0;
+}
+
+int gen_license_req_cb(const char *resp_data, const char *cookie, char **req_data, char **license_url, int *ret)
+{
+ __register_signal_handler();
+
+ _LOGE(">> in callback >> package_manager_drm_generate_license_request is called.");
+
+ if (resp_data == NULL || req_data == NULL || license_url == NULL || cookie == NULL) {
+ _LOGE("Invalid parameter.");
+ *ret = PKGMGR_R_EINVAL;
+ __set_drm_busy(0);
+ return -1;
+ }
+ int retval = 0;
+ char temp_req_data[1024] = {0,};
+ unsigned int temp_req_len = sizeof(temp_req_data);
+ char temp_license_url[1024] = {0,};
+ unsigned int temp_license_url_len = sizeof(temp_license_url);
+ int cookie_result = 0;
+
+ cookie_result = __check_admin_privilege_by_cookie(cookie);
+ if (cookie_result < 0){
+ _LOGE("__check_admin_privilege_by_cookie result fail[%d]", cookie_result);
+ *ret = PKGMGR_R_EPRIV;
+ return -1;
+ }
+
+ retval = drm_tizen_generate_license_request(resp_data, strlen(resp_data), temp_req_data, &temp_req_len, temp_license_url, &temp_license_url_len);
+ if (retval != 1) {
+ _LOGE("drm_tizen_generate_license_request is failed.");
+ *ret = PKGMGR_R_ERROR;
+ __set_drm_busy(0);
+ return -1;
+ }
+
+ *req_data = strdup(temp_req_data);
+ *license_url = strdup(temp_license_url);
+
+ _LOGD("package_manager_drm_generate_license_request is successful.");
+ *ret = PKGMGR_R_OK;
+ __set_drm_busy(1);
+
+ return 0;
+}
+#endif
+
+int create_external_dir_cb(const char *zone)
+{
+ int err = -1;
+ int p = 0;
+
+ SECURE_LOGD(">> in callback >> External storage has been mounted");
+
+ __register_signal_handler();
+
+ pm_dbus_msg *item = calloc(1, sizeof(pm_dbus_msg));
+ if (item == NULL)
+ {
+ _LOGE("Out of memory");
+ return err;
+ }
+
+ item->req_type = COMM_REQ_MAKE_EXTERNAL_DIR;
+ strncpy(item->pkg_type, "rpm", sizeof(item->pkg_type) - 1);
+ strncpy(item->backend_installer, "rpm", sizeof(item->backend_installer) - 1);
+ if (zone) {
+ strncpy(item->zone, zone, sizeof(item->zone) - 1);
+ _LOGD("zone(%s), item->zone(%s)", zone, item->zone);
+ }
+
+ 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);
+ }
+
+ free(item);
+
+ return err;
+}
+
+void req_cb(void *cb_data, const char *req_id, const int req_type,
+ const char *pkg_type, const char *pkgid, const char *args,
+ const char *cookie, const char *zone, int *ret)
+{
+ int err = -1;
+ int p = 0;
+ int cookie_result = 0;
+
+ SECURE_LOGD(">> in callback >> Got request: [%s] [%d] [%s] [%s] [%s] [%s] [%s]",
+ req_id, req_type, pkg_type, pkgid, args, cookie, zone);
+
+ __register_signal_handler();
+
+ pm_dbus_msg *item = calloc(1, sizeof(pm_dbus_msg));
+ if (item == NULL)
+ {
+ _LOGE("Out of memory");
+ return;
+ }
+
+ strncpy(item->req_id, req_id, sizeof(item->req_id) - 1);
+ item->req_type = req_type;
+ strncpy(item->pkg_type, pkg_type, sizeof(item->pkg_type) - 1);
+
+ strncpy(item->pkgid, pkgid, sizeof(item->pkgid) - 1);
+ strncpy(item->args, args, sizeof(item->args) - 1);
+ strncpy(item->cookie, cookie, sizeof(item->cookie) - 1);
+ if (zone) {
+ strncpy(item->zone, zone, sizeof(item->zone) - 1);
+ _LOGD("req_type=(%d) backend_flag=(%d) zone(%s)",
+ req_type, backend_flag, item->zone);
+ }
+
+ switch (item->req_type) {
+ case COMM_REQ_TO_INSTALL:
+ /* 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]", cookie_result);
+ *ret = PKGMGR_R_EPRIV;
+ goto err;
+ }
+
+ /* get pkgtype from msg-args */
+ if (_zone_set_type_and_backend(item, zone)) {
+ *ret = PKGMGR_R_ERROR;
+ goto err;
+ }
+
+ /* quiet mode */
+ err = _pm_queue_push(item);
+ p = __get_position_from_pkg_type(item->pkg_type);
+ if (p < 0) {
+ _LOGE("invalid or unsupported package");
+ *ret = PKGMGR_R_ERROR;
+ break;
+ }
+ __set_backend_mode(p);
+ if (err == 0)
+ g_idle_add(queue_job, NULL);
+ *ret = PKGMGR_R_OK;
+ break;
+ case COMM_REQ_TO_UNINSTALL:
+ /* 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]", cookie_result);
+ *ret = PKGMGR_R_EPRIV;
+ goto err;
+ }
+
+ /* quiet mode */
+ err = _pm_queue_push(item);
+ p = __get_position_from_pkg_type(item->pkg_type);
+ if (p < 0) {
+ _LOGE("invalid or unsupported package");
+ *ret = PKGMGR_R_ERROR;
+ break;
+ }
+ __set_backend_mode(p);
+ if (err == 0)
+ g_idle_add(queue_job, NULL);
+ *ret = PKGMGR_R_OK;
+ break;
+ case COMM_REQ_ACTIVATE_PKG:
+ 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;
+ case COMM_REQ_DEACTIVATE_PKG:
+ 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;
+ case COMM_REQ_ACTIVATE_APP:
+ 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;
+ case COMM_REQ_DEACTIVATE_APP:
+ 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;
+ case COMM_REQ_ENABLE_BG_OPERATION:
+ 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;
+ case COMM_REQ_DISABLE_BG_OPERATION:
+ 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;
+
+ case COMM_REQ_ACTIVATE_APP_WITH_LABEL:
+ 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;
+ case COMM_REQ_TO_CLEARER:
+ /* In case of clearer, there is no popup */
+ err = _pm_queue_push(item);
+ p = __get_position_from_pkg_type(item->pkg_type);
+ /*the backend shows the success/failure popup
+ so this request is non quiet*/
+ __unset_backend_mode(p);
+
+/* g_idle_add(queue_job, NULL); */
+ if (err == 0)
+ queue_job(NULL);
+ *ret = PKGMGR_R_OK;
+ break;
+ case COMM_REQ_TO_MOVER:
+ /* check caller privilege */
+ cookie_result = __check_privilege_by_cookie(cookie, item->req_type);
+ if (cookie_result < 0){
+ _LOGD("__check_privilege_by_cookie result fail[%d]", cookie_result);
+ *ret = PKGMGR_R_EPRIV;
+ goto err;
+ }
+
+ /* In case of mover, there is no popup */
+ err = _pm_queue_push(item);
+ p = __get_position_from_pkg_type(item->pkg_type);
+ if (p < 0) {
+ _LOGE("invalid or unsupported package");
+ *ret = PKGMGR_R_ERROR;
+ goto err;
+ }
+
+ /*the backend shows the success/failure popup
+ so this request is non quiet*/
+ __unset_backend_mode(p);
+ if (err == 0)
+ queue_job(NULL);
+ *ret = PKGMGR_R_OK;
+ break;
+ case COMM_REQ_CANCEL:
+ _pm_queue_delete(item);
+ p = __get_position_from_pkg_type(item->pkg_type);
+ __unset_backend_mode(p);
+ *ret = PKGMGR_R_OK;
+ break;
+ case COMM_REQ_GET_SIZE:
+ /* check caller privilege */
+#ifdef _APPFW_PKGMGR_PRIV_SUPPORT //XXX: Temporary define
+ cookie_result = __check_privilege_by_cookie(cookie, item->req_type);
+ if (cookie_result < 0){
+ _LOGE("__check_privilege_by_cookie result fail[%d]", cookie_result);
+ *ret = PKGMGR_R_EPRIV;
+ goto err;
+ }
+#endif
+ 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;
+
+ case COMM_REQ_CHECK_APP:
+ case COMM_REQ_KILL_APP:
+ /* In case of activate, there is no popup */
+ err = _pm_queue_push(item);
+ p = __get_position_from_pkg_type(item->pkg_type);
+ __set_backend_mode(p);
+
+/* g_idle_add(queue_job, NULL); */
+ if (err == 0)
+ queue_job(NULL);
+ *ret = PKGMGR_R_OK;
+ break;
+
+ case COMM_REQ_CLEAR_CACHE_DIR:
+ /* check caller privilege */
+#ifdef _APPFW_PKGMGR_PRIV_SUPPORT //XXX: Temporary define
+ cookie_result = __check_privilege_by_cookie(cookie, item->req_type);
+ if (cookie_result < 0){
+ _LOGE("__check_privilege_by_cookie result fail[%d]", cookie_result);
+ *ret = PKGMGR_R_EPRIV;
+ goto err;
+ }
+#endif
+ 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:
+ _LOGE("Check your request..");
+ *ret = PKGMGR_R_ERROR;
+ break;
+ }
+err:
+ if (*ret != PKGMGR_R_OK) {
+ _LOGD("Failed to handle request %s %s", item->pkg_type, item->pkgid);
+ pkgmgr_installer *pi;
+ gboolean ret_parse;
+ gint argcp;
+ gchar **argvp;
+ GError *gerr = NULL;
+
+ pi = pkgmgr_installer_new();
+ if (!pi) {
+ _LOGE("Failure in creating the pkgmgr_installer object");
+ if(item){
+ free(item);
+ item = NULL;
+ }
+ return;
+ }
+
+ ret_parse = g_shell_parse_argv(args, &argcp, &argvp, &gerr);
+ if (FALSE == ret_parse) {
+ _LOGE("Failed to split args: %s", args);
+ _LOGE("messsage: %s", gerr->message);
+ pkgmgr_installer_free(pi);
+ if(item){
+ free(item);
+ item = NULL;
+ }
+ return;
+ }
+
+ pkgmgr_installer_receive_request(pi, argcp, argvp);
+
+ pkgmgr_installer_send_signal(pi, item->pkg_type,
+ item->pkgid, "end",
+ "fail");
+
+ pkgmgr_installer_free(pi);
+
+ }
+
+ if(item){
+ free(item);
+ item = NULL;
+ }
+ return;
+}
+
+#ifdef _APPFW_FEATURE_EXPANSION_PKG_INSTALL
+void req_tep_cb(void *cb_data, const char *req_id, const int req_type,
+ const char *pkg_type, const char *pkgid,const char *tep_path,
+ const char *args, const char *cookie, const char *zone, int *ret)
+{
+ int err = -1;
+ int p = 0;
+ int cookie_result = 0;
+
+ _LOGE("req_id=[%s], req_type=[%d], pkg_type=[%s], pkgid=[%s], tep_path[%s], args=[%s], cookie=[%s], backend_flag=[%d], zone=[%s]",
+ req_id, req_type, pkg_type, pkgid, tep_path, args, cookie, backend_flag, zone);
+
+ __register_signal_handler();
+
+ pm_dbus_msg *item = calloc(1, sizeof(pm_dbus_msg));
+ if (item == NULL)
+ {
+ _LOGE("Out of memory");
+ return;
+ }
+
+ strncpy(item->req_id, req_id, sizeof(item->req_id) - 1);
+ item->req_type = req_type;
+ if (pkg_type)
+ strncpy(item->pkg_type, pkg_type, sizeof(item->pkg_type) - 1);
+
+ if (pkgid && strlen(pkgid)>0)
+ strncpy(item->pkgid, pkgid, sizeof(item->pkgid) - 1);
+ else
+ item->pkgid[0] = '\0';
+
+ if (tep_path)
+ strncpy(item->tep_path, tep_path, sizeof(item->tep_path) - 1);
+
+ strncpy(item->args, args, sizeof(item->args) - 1);
+ strncpy(item->cookie, cookie, sizeof(item->cookie) - 1);
+ if (zone) {
+ strncpy(item->zone, zone, sizeof(item->zone) - 1);
+ _LOGD("req_type=(%d) backend_flag=(%d) zone(%s)",
+ req_type, backend_flag, item->zone);
+ }
+
+ switch (item->req_type) {
+ case COMM_REQ_TO_INSTALL:
+ /* 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;
+ }
+
+ /* get pkgtype from msg-args */
+ if (_zone_set_type_and_backend(item, zone)) {
+ *ret = PKGMGR_R_ERROR;
+ goto err;
+ }
+ _LOGE("pkg type[%s]", item->pkg_type);
+
+ /* quiet mode */
+ err = _pm_queue_push(item);
+ p = __get_position_from_pkg_type(item->pkg_type);
+ if (p < 0) {
+ _LOGE("invalid or unsupported package");
+ *ret = PKGMGR_R_ERROR;
+ break;
+ }
+ __set_backend_mode(p);
+ if (err == 0)
+ g_idle_add(queue_job, NULL);
+ *ret = PKGMGR_R_OK;
+ break;
+ case COMM_REQ_TO_UNINSTALL:
+ /* 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;
+ }
+
+ _LOGE("pkg type[%s]", item->pkg_type);
+
+ /* quiet mode */
+ err = _pm_queue_push(item);
+ p = __get_position_from_pkg_type(item->pkg_type);
+ if (p < 0) {
+ _LOGE("invalid or unsupported package");
+ *ret = PKGMGR_R_ERROR;
+ break;
+ }
+ __set_backend_mode(p);
+ if (err == 0)
+ g_idle_add(queue_job, NULL);
+ *ret = PKGMGR_R_OK;
+ break;
+
+
+ case COMM_REQ_ACTIVATE_PKG:
+ 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;
+ case COMM_REQ_DEACTIVATE_PKG:
+ 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;
+ case COMM_REQ_ACTIVATE_APP:
+ 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;
+ case COMM_REQ_DEACTIVATE_APP:
+ 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;
+ case COMM_REQ_ACTIVATE_APP_WITH_LABEL:
+ 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;
+ case COMM_REQ_TO_CLEARER:
+ /* In case of clearer, there is no popup */
+ err = _pm_queue_push(item);
+ p = __get_position_from_pkg_type(item->pkg_type);
+ /*the backend shows the success/failure popup
+ so this request is non quiet*/
+ __unset_backend_mode(p);
+
+ /* g_idle_add(queue_job, NULL); */
+ if (err == 0)
+ queue_job(NULL);
+ *ret = PKGMGR_R_OK;
+ break;
+ case COMM_REQ_TO_MOVER:
+ /* check caller privilege */
+ cookie_result = __check_privilege_by_cookie(cookie, item->req_type);
+ if (cookie_result < 0){
+ _LOGD("__check_privilege_by_cookie result fail[%d]\n", cookie_result);
+ *ret = PKGMGR_R_EPRIV;
+ goto err;
+ }
+
+ /* In case of mover, there is no popup */
+ err = _pm_queue_push(item);
+ p = __get_position_from_pkg_type(item->pkg_type);
+ /*the backend shows the success/failure popup
+ so this request is non quiet*/
+ __unset_backend_mode(p);
+ if (err == 0)
+ queue_job(NULL);
+ *ret = PKGMGR_R_OK;
+ break;
+ case COMM_REQ_CANCEL:
+ _pm_queue_delete(item);
+ p = __get_position_from_pkg_type(item->pkg_type);
+ __unset_backend_mode(p);
+ *ret = PKGMGR_R_OK;
+ break;
+ case COMM_REQ_GET_SIZE:
+ /* 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;
+
+ case COMM_REQ_CHECK_APP:
+ case COMM_REQ_KILL_APP:
+ /* In case of activate, there is no popup */
+ err = _pm_queue_push(item);
+ p = __get_position_from_pkg_type(item->pkg_type);
+ __set_backend_mode(p);
+
+ /* g_idle_add(queue_job, NULL); */
+ if (err == 0)
+ queue_job(NULL);
+ *ret = PKGMGR_R_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;
+ }
+#if 0
+ if (__is_clearing_cache_running(item->pkgid)) {
+ *ret = PKGMGR_R_OK;
+ break;
+ }
+#endif
+ 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:
+ _LOGE("Check your request..\n");
+ *ret = PKGMGR_R_ERROR;
+ break;
+ }
+err:
+ if (*ret != PKGMGR_R_OK) {
+ _LOGD("Failed to handle request %s %s\n",item->pkg_type, item->pkgid);
+ pkgmgr_installer *pi;
+ gboolean ret_parse;
+ gint argcp;
+ gchar **argvp;
+ GError *gerr = NULL;
+
+ pi = pkgmgr_installer_new();
+ if (!pi) {
+ _LOGE("Failure in creating the pkgmgr_installer object");
+ if(item){
+ free(item);
+ item = NULL;
+ }
+ return;
+ }
+
+ ret_parse = g_shell_parse_argv(args, &argcp, &argvp, &gerr);
+ if (FALSE == ret_parse) {
+ _LOGE("Failed to split args: %s", args);
+ _LOGE("messsage: %s", gerr->message);
+ pkgmgr_installer_free(pi);
+ if(item){
+ free(item);
+ item = NULL;
+ }
+ return;
+ }
+
+ pkgmgr_installer_receive_request(pi, argcp, argvp);
+
+ pkgmgr_installer_send_signal(pi, item->pkg_type,
+ item->pkgid, "end",
+ "fail");
+
+ pkgmgr_installer_free(pi);
+
+ }
+
+ if(item){
+ free(item);
+ item = NULL;
+ }
+ return;
+}
+#endif
+
+static int __check_drm_status_for_exit()
+{
+ if (drm_busy)
+ return 0;
+ else
+ return 1;
+}
+
+static int __check_backend_status_for_exit()
+{
+ int i = 0;
+ for(i = 0; i < num_of_backends; i++)
+ {
+ if (!__is_backend_busy(i))
+ continue;
+ else
+ return 0;
+ }
+ return 1;
+}
+
+static int __check_queue_status_for_exit()
+{
+ pm_queue_data *head[MAX_QUEUE_NUM] = {NULL,};
+ queue_info_map *ptr = NULL;
+ ptr = start;
+ int i = 0;
+ int c = 0;
+ int slot = -1;
+ for(i = 0; i < entries; i++)
+ {
+ if (ptr->queue_slot <= slot) {
+ ptr++;
+ continue;
+ }
+ else {
+ head[c] = ptr->head;
+ slot = ptr->queue_slot;
+ c++;
+ ptr++;
+ }
+ }
+ for(i = 0; i < num_of_backends; i++)
+ {
+ if (!head[i])
+ continue;
+ else
+ return 0;
+ }
+ return 1;
+}
+
+gboolean exit_server(void *data)
+{
+ _LOGE("exit_server Start [backend_status=%d, queue_status=%d, drm_status=%d] \n", __check_backend_status_for_exit(), __check_queue_status_for_exit(), __check_drm_status_for_exit());
+ if (__check_backend_status_for_exit() && __check_queue_status_for_exit() && __check_drm_status_for_exit()) {
+ if (!getenv("PMS_STANDALONE")) {
+ g_main_loop_quit(mainloop);
+ return FALSE;
+ }
+ }
+ return TRUE;
+}
+
+static int __terminate_app(const aul_app_info *ainfo, void *data)
+{
+ retvm_if(ainfo == NULL, -1, "ainfo is null\n");
+ retvm_if(ainfo->appid == NULL, -1, "appid is null\n");
+
+ int ret = 0;
+
+ if (!strcmp(ainfo->appid, (char *)data)) {
+
+ ret = aul_terminate_pid_without_restart(ainfo->pid);
+ retvm_if(ret < 0, -1, "aul_terminate_pid[%d] fail\n", ret);
+
+ int i = 0;
+ for (i = 0; i < 50; i++) {
+ if (aul_app_is_running(ainfo->appid))
+ usleep(100 * 1000); /* 100ms sleep*/
+ else
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static int __terminate_running_app_cb(const pkgmgrinfo_appinfo_h handle, void *user_data)
+{
+ retvm_if(handle == NULL, -1, "handle is null\n");
+
+ int ret = 0;
+ char *appid = NULL;
+
+ ret = pkgmgrinfo_appinfo_get_appid(handle, &appid);
+ retvm_if(ret < 0, -1, "get_appid fail\n");
+
+ if (aul_app_is_running(appid)) {
+ ret = aul_app_get_running_app_info(__terminate_app, appid);
+ retvm_if(ret < 0, -1, "terminate_app[%s] fail\n", appid);
+ }
+
+ return 0;
+}
+
+int __terminate_running_app(const char *pkgid)
+{
+ int ret = 0;
+ pkgmgrinfo_pkginfo_h handle = NULL;
+
+ ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &handle);
+ if (ret == 0) {
+ ret = pkgmgrinfo_appinfo_get_list(handle, PMINFO_UI_APP, __terminate_running_app_cb, NULL);
+ if (ret < 0) {
+ _LOGE("pkgmgrinfo_appinfo_get_list() failed\n");
+ }
+ pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+ }
+ return 0;
+}
+
+static int __iter_cb(const aul_app_info *ainfo, void *data)
+{
+ pm_appinfo *pmappinfo = (pm_appinfo *)data;
+ int pgid;
+
+ if (strcmp(ainfo->app_path, pmappinfo->apppath) == 0) {
+ _LOGD("terminate app apppath[%s], pid[%d]\n", ainfo->app_path, ainfo->pid);
+ if (pmappinfo->option == 0) {
+ pmappinfo->pid = ainfo->pid;
+ return ainfo->pid;
+ }
+
+ pgid = getpgid(ainfo->pid);
+ if (pgid <= 1) {
+ return -1;
+ }
+ if (killpg(pgid, SIGKILL) < 0) {
+ return -1;
+ }
+ pmappinfo->pid = ainfo->pid;
+ return ainfo->pid;
+ }
+
+ return 0;
+}
+
+static int __pkgcmd_proc_iter_kill_cmdline(const char *apppath,
+ const char *zone, int option)
+{
+ int ret;
+
+ pm_appinfo pmappinfo;
+ pmappinfo.apppath = apppath;
+ pmappinfo.option = option;
+
+ ret = aul_app_get_running_app_info(__iter_cb, &pmappinfo);
+ if (ret < 0)
+ return 0;
+
+ return pmappinfo.pid;
+}
+
+static void __make_pid_info_file(char *req_key, int size, int is_zone)
+{
+ int ret = 0;
+ FILE* file = NULL;
+ int fd = 0;
+ char buf[MAX_PKG_TYPE_LEN] = {0};
+ const char* app_info_label = "*";
+ char info_file[PATH_MAX] = {'\0'};
+ char *cano_path = NULL;
+
+ if(req_key == NULL)
+ return;
+
+ snprintf(info_file, PATH_MAX, "tmp/%s", req_key);
+ if (is_zone) {
+ ret = vsm_canonicalize_path(info_file, &cano_path);
+ if (ret < 0) {
+ _LOGE("vsm canonicalize path error(%d)", ret);
+ return;
+ }
+ if (cano_path == NULL) {
+ _LOGE("cano_path is NULL");
+ return;
+ }
+ }
+
+ if (!cano_path) {
+ cano_path = strdup(info_file);
+ if (!cano_path) {
+ _LOGE("strdup failed");
+ return;
+ }
+ }
+
+ _LOGD("cano_path(%s)", cano_path);
+ file = fopen(cano_path, "w");
+ if (file == NULL) {
+ _LOGE("Couldn't open the file(%s)", cano_path);
+ goto out;
+ }
+
+ snprintf(buf, MAX_PKG_TYPE_LEN, "%d\n", size);
+ fwrite(buf, 1, strlen(buf), file);
+
+ fflush(file);
+ fd = fileno(file);
+ fsync(fd);
+ fclose(file);
+
+ if (security_server_label_access(info_file, app_info_label) != 0) {
+ _LOGE("error(%d) in setting smack label", errno);
+ goto out;
+ } else {
+ _LOGD("security_server_label_access(%s, %s) is ok.", info_file, app_info_label);
+ }
+
+ ret = chmod(cano_path, 0777);
+ if(ret < 0)
+ goto out;
+
+ ret = chown(cano_path, 5000, 5000);
+ if(ret < 0)
+ goto out;
+
+out:
+ if (cano_path)
+ free(cano_path);
+}
+
+static int __pkgcmd_app_cb(const pkgmgrinfo_appinfo_h handle, void *user_data)
+{
+ char *pkgid = NULL;
+ char *exec = NULL;
+ int ret = 0;
+ int pid = -1;
+
+ struct vsm_context *ctx = NULL;
+ vsm_zone_h effective_zone, real_zone;
+
+ if (handle == NULL) {
+ perror("appinfo handle is NULL");
+ exit(1);
+ }
+ ret = pkgmgrinfo_appinfo_get_exec(handle, &exec);
+ if (ret) {
+ perror("Failed to get app exec path");
+ exit(1);
+ }
+ ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid);
+ if (ret) {
+ perror("Failed to get appid");
+ exit(1);
+ }
+
+ if (!user_data) {
+ _LOGE("user_data is NULL");
+ return 0;
+ }
+
+ checkapp_data_s *kc_data = (checkapp_data_s *)user_data;
+ char *sub_cmd = kc_data->sub_cmd;
+ char *zone_name = kc_data->zone_name;
+ int is_zone = 0;
+
+ if (zone_name && strlen(zone_name) && strcmp(zone_name, ZONE_HOST) != 0) {
+ is_zone = 1;
+ }
+
+ dbg("sub_cmd(%s), zone_name(%s)", sub_cmd, zone_name);
+
+ if (is_zone) {
+ ctx = vsm_create_context();
+ if (!ctx) {
+ _LOGE("failed to create vsm context");
+ return -1;
+ }
+ effective_zone = vsm_lookup_zone_by_name(ctx, zone_name);
+ real_zone = vsm_join_zone(effective_zone);
+ }
+
+ if (strcmp(sub_cmd, "kill") == 0)
+ pid = __terminate_running_app(pkgid);
+ else if (strcmp(sub_cmd, "check") == 0)
+ pid = __pkgcmd_proc_iter_kill_cmdline(exec, zone_name, 0);
+
+ __make_pid_info_file(pkgid, pid ,is_zone);
+
+ if (is_zone) {
+ vsm_join_zone(real_zone);
+ vsm_cleanup_context(ctx);
+ }
+
+ return 0;
+}
+
+static char *__get_signal_name(char *post_name, const char *pre_name, const char *zone)
+{
+ memset(post_name, 0, MAX_ZONE_NAME_LEN);
+ if (zone && strlen(zone) && strcmp(zone, ZONE_HOST) != 0) {
+ snprintf(post_name, MAX_ZONE_NAME_LEN, "%s_", pre_name);
+ strncat(post_name, zone, MAX_ZONE_NAME_LEN - strlen(post_name) - 1);
+ } else {
+ snprintf(post_name, MAX_ZONE_NAME_LEN, "%s", pre_name);
+ }
+ dbg("signal name : (%s -> %s)", pre_name, post_name);
+
+ return post_name;
+}
+
+void __pm_send_sub_signal(const char *req_id, const char *pkg_type, const char *pkgid,
+ const char *key, const char *val, const char *zone)
+{
+ dbus_uint32_t serial = 0;
+ DBusMessage *msg = NULL;
+ DBusMessageIter args;
+ DBusError err;
+ DBusConnection *conn = NULL;
+ const char *values[] = {
+ req_id,
+ pkg_type,
+ pkgid,
+ key,
+ val
+ };
+ int i;
+
+ dbus_error_init(&err);
+
+ conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
+ if (dbus_error_is_set(&err)) {
+ _LOGE("Connection error: %s", err.message);
+ dbus_error_free(&err);
+ }
+ dbus_error_free(&err);
+ if (NULL == conn) {
+ _LOGE("conn is NULL");
+ return;
+ }
+
+ char signal_name[128] = {0, };
+
+ if (strcmp(key,PKGMGR_INSTALLER_START_KEY_STR) == 0) {
+ if (strcmp(val,PKGMGR_INSTALLER_INSTALL_EVENT_STR) == 0) {
+ msg = dbus_message_new_signal(COMM_STATUS_BROADCAST_DBUS_INSTALL_PATH, COMM_STATUS_BROADCAST_DBUS_INSTALL_INTERFACE,
+ __get_signal_name(signal_name, COMM_STATUS_BROADCAST_EVENT_INSTALL, zone));
+ } else if (strcmp(val,PKGMGR_INSTALLER_UNINSTALL_EVENT_STR) == 0) {
+ msg = dbus_message_new_signal(COMM_STATUS_BROADCAST_DBUS_UNINSTALL_PATH, COMM_STATUS_BROADCAST_DBUS_UNINSTALL_INTERFACE,
+ __get_signal_name(signal_name, COMM_STATUS_BROADCAST_EVENT_UNINSTALL, zone));
+ } else if (strcmp(val,PKGMGR_INSTALLER_UPGRADE_EVENT_STR) == 0) {
+ msg = dbus_message_new_signal(COMM_STATUS_BROADCAST_DBUS_UPGRADE_PATH, COMM_STATUS_BROADCAST_DBUS_UPGRADE_INTERFACE,
+ __get_signal_name(signal_name, COMM_STATUS_BROADCAST_EVENT_UPGRADE, zone));
+ }
+ } else if (strcmp(key,PKGMGR_INSTALLER_END_KEY_STR) == 0) {
+ if (strcmp(req_id,PKGMGR_INSTALLER_INSTALL_EVENT_STR) == 0) {
+ msg = dbus_message_new_signal(COMM_STATUS_BROADCAST_DBUS_INSTALL_PATH, COMM_STATUS_BROADCAST_DBUS_INSTALL_INTERFACE,
+ __get_signal_name(signal_name, COMM_STATUS_BROADCAST_EVENT_INSTALL, zone));
+ } else if (strcmp(req_id,PKGMGR_INSTALLER_UNINSTALL_EVENT_STR) == 0) {
+ msg = dbus_message_new_signal(COMM_STATUS_BROADCAST_DBUS_UNINSTALL_PATH, COMM_STATUS_BROADCAST_DBUS_UNINSTALL_INTERFACE,
+ __get_signal_name(signal_name, COMM_STATUS_BROADCAST_EVENT_UNINSTALL, zone));
+ } else if (strcmp(req_id,PKGMGR_INSTALLER_UPGRADE_EVENT_STR) == 0) {
+ msg = dbus_message_new_signal(COMM_STATUS_BROADCAST_DBUS_UPGRADE_PATH, COMM_STATUS_BROADCAST_DBUS_UPGRADE_INTERFACE,
+ __get_signal_name(signal_name, COMM_STATUS_BROADCAST_EVENT_UPGRADE, zone));
+ }
+ }
+ if (NULL == msg) {
+ _LOGE("msg NULL");
+ return;
+ }
+
+ dbus_message_iter_init_append(msg, &args);
+
+ for (i = 0; i < 5; i++) {
+ if (!dbus_message_iter_append_basic
+ (&args, DBUS_TYPE_STRING, &(values[i]))) {
+ _LOGE("dbus_message_iter_append_basic failed:"
+ " Out of memory");
+ return;
+ }
+ }
+ if (!dbus_connection_send(conn, msg, &serial)) {
+ _LOGE("dbus_connection_send failed: Out of memory");
+ return;
+ }
+ dbus_connection_flush(conn);
+ dbus_message_unref(msg);
+}
+
+void __pm_send_signal(const char *req_id, const char *pkg_type, const char *pkgid,
+ const char *key, const char *val, const char *zone)
+{
+ dbus_uint32_t serial = 0;
+ DBusMessage *msg;
+ DBusMessageIter args;
+ DBusError err;
+ DBusConnection *conn;
+ const char *values[] = {
+ req_id,
+ pkg_type,
+ pkgid,
+ key,
+ val
+ };
+ int i;
+
+ dbus_error_init(&err);
+
+ conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
+ if (dbus_error_is_set(&err)) {
+ _LOGE("Connection error: %s", err.message);
+ dbus_error_free(&err);
+ }
+ dbus_error_free(&err);
+ if (NULL == conn) {
+ _LOGE("conn is NULL");
+ return;
+ }
+
+ char signal_name[128] = {0, };
+
+ msg = dbus_message_new_signal(COMM_STATUS_BROADCAST_DBUS_PATH, COMM_STATUS_BROADCAST_DBUS_INTERFACE,
+ __get_signal_name(signal_name, COMM_STATUS_BROADCAST_SIGNAL_STATUS, zone));
+ if (NULL == msg) {
+ _LOGE("msg NULL");
+ return;
+ }
+
+ dbus_message_iter_init_append(msg, &args);
+
+ for (i = 0; i < 5; i++) {
+ if (!dbus_message_iter_append_basic
+ (&args, DBUS_TYPE_STRING, &(values[i]))) {
+ _LOGE("dbus_message_iter_append_basic failed: Out of memory");
+ return;
+ }
+ }
+ if (!dbus_connection_send(conn, msg, &serial)) {
+ _LOGE("dbus_connection_send failed: Out of memory");
+ return;
+ }
+ dbus_connection_flush(conn);
+ dbus_message_unref(msg);
+
+ __pm_send_sub_signal(req_id, pkg_type, pkgid, key, val, zone);
+}
+
+void __change_item_info(pm_dbus_msg *item)
+{
+ int ret = 0;
+ char *pkgid = NULL;
+ pkgmgrinfo_appinfo_h handle = NULL;
+
+ ret = pkgmgrinfo_appinfo_get_appinfo(item->pkgid, &handle);
+ if (ret != PMINFO_R_OK)
+ return;
+
+ ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid);
+ if (ret != PMINFO_R_OK) {
+ pkgmgrinfo_appinfo_destroy_appinfo(handle);
+ return;
+ }
+
+ memset((item->pkgid),0,MAX_PKG_NAME_LEN);
+ strncpy(item->pkgid, pkgid, sizeof(item->pkgid) - 1);
+
+ pkgmgrinfo_appinfo_destroy_appinfo(handle);
+}
+
+static char **__generate_argv(const char *args)
+{
+ /* Create args vector
+ * req_id + pkgid + args
+ *
+ * vector size = # of args +
+ *(req_id + pkgid + NULL termination = 3)
+ * Last value must be NULL for execv.
+ */
+ gboolean ret_parse;
+ gint argcp;
+ gchar **argvp;
+ GError *gerr = NULL;
+ ret_parse = g_shell_parse_argv(args,
+ &argcp, &argvp, &gerr);
+ if (FALSE == ret_parse) {
+ _LOGE("Failed to split args: %s", args);
+ _LOGE("messsage: %s", gerr->message);
+ exit(1);
+ }
+
+ /* Setup argument !!! */
+ /*char **args_vector =
+ calloc(argcp + 4, sizeof(char *)); */
+ char **args_vector = calloc(argcp + 1, sizeof(char *));
+ if (args_vector == NULL)
+ {
+ _LOGE("Out of memory");
+ exit(1);
+ }
+ /*args_vector[0] = strdup(backend_cmd);
+ args_vector[1] = strdup(item->req_id);
+ args_vector[2] = strdup(item->pkgid); */
+ int arg_idx;
+ for (arg_idx = 0; arg_idx < argcp; arg_idx++) {
+ /* args_vector[arg_idx+3] = argvp[arg_idx]; */
+ args_vector[arg_idx] = argvp[arg_idx];
+ }
+
+ /* dbg */
+ /*for(arg_idx = 0; arg_idx < argcp+3; arg_idx++) { */
+ for (arg_idx = 0; arg_idx < argcp + 1; arg_idx++) {
+ _LOGD(">>>>>> args_vector[%d]=%s", arg_idx, args_vector[arg_idx]);
+ }
+
+ return args_vector;
+}
+
+static void __exec_with_arg_vector(const char *cmd, char **argv, const char *zone)
+{
+ char *backend_cmd = strdup(cmd);
+ if (NULL == backend_cmd)
+ {
+ perror("Out of memory");
+ exit(1);
+ }
+
+ _LOGD("Try to exec [%s]", backend_cmd);
+ fprintf(stdout, "Try to exec [%s]\n", backend_cmd);
+
+ /* Execute backend !!! */
+ int ret = 0;
+
+ char **zone_args = NULL;
+ int is_zone = 0;
+
+ if (zone && strlen(zone) && strcmp(zone, ZONE_HOST) != 0) {
+ _LOGD("Try to exec [%s] zone[%s]", backend_cmd, zone);
+ fprintf(stdout, "Try to exec [%s] [%s]\n", backend_cmd, zone);
+
+ is_zone = 1;
+ }
+
+ if (is_zone) {
+ int count = 0;
+ while (NULL != argv) {
+ if (NULL == argv[count])
+ break;
+ const char *arv_str = argv[count];
+ _LOGD("backend argv[%d] = %s", count, arv_str);
+ count++;
+ }
+ count++; /* for last NULL argument*/
+
+ _LOGD("backend argv count = %d", count);
+
+ char *zone_cmd = "/usr/bin/lxc-attach";
+ zone_args = calloc(count + 5, sizeof(char *));
+ if (NULL == zone_args) {
+ _LOGE("out of memory for zone_args");
+ exit(1);
+ }
+ zone_args[count + 4] = NULL;
+ zone_args[0] = "/usr/bin/lxc-attach";
+ zone_args[1] = "-n";
+ zone_args[2] = (char *)zone;
+ zone_args[3] = "--";
+ zone_args[4] = backend_cmd;
+
+ char cmd_buff[256] = {0, };
+ char tmp_buff[256] = {0, };
+ snprintf(cmd_buff, 256, "%s", backend_cmd);
+ int i;
+ for (i = 0; i < count; i++) {
+ const char *arv_str = argv[i];
+ snprintf(tmp_buff, 256, "%s %s", cmd_buff, arv_str);
+ snprintf(cmd_buff, 256, "%s", tmp_buff);
+ zone_args[5 + i] = argv[i];
+ }
+ _LOGD("zone cmd_buff = %s", cmd_buff);
+ for (i = 0; i < (count + 5); i++) {
+ _LOGD("zone_args[%d] = %s", i, zone_args[i]);
+ }
+
+ ret = execv(zone_cmd, zone_args);
+ } else {
+ ret = execv(backend_cmd, argv);
+ }
+
+ /* Code below: exec failure. Should not be happened! */
+ _LOGD(">>>>>> OOPS 2!!!");
+
+ /* g_strfreev(args_vector); *//* FIXME: causes error */
+
+ if (ret == -1) {
+ perror("fail to exec");
+ exit(1);
+ }
+ if (NULL != backend_cmd)
+ free(backend_cmd);
+ if (NULL != zone_args)
+ free(zone_args);
+}
+
+static int __zone_set_activation_info(char *pkgid, int is_active, char *label, const char *zone)
+{
+ char activation_info_file[MAX_PKG_NAME_LEN] = { 0, };
+
+ if (zone && strlen(zone) && strcmp(zone, ZONE_HOST) != 0) {
+ char *rootpath = NULL;
+ rootpath = _zone_get_root_path(zone);
+ if (rootpath == NULL) {
+ _LOGE("rootpath is null");
+ return PMINFO_R_ERROR;
+ }
+ snprintf(activation_info_file, MAX_PKG_NAME_LEN, "%s%s/%s", rootpath, PKG_DATA_PATH, pkgid);
+ } else {
+ snprintf(activation_info_file, MAX_PKG_NAME_LEN, "%s/%s", PKG_DATA_PATH, pkgid);
+ }
+
+ if (is_active) {
+ int ret = 0;
+ const char* app_info_label = "_";
+
+ if (security_server_label_access(activation_info_file, app_info_label) != 0) {
+ _LOGE("error(%d) in setting smack label",errno);
+ return PMINFO_R_ERROR;
+ } else {
+ _LOGD("security_server_label_access(%s, %s) is ok.", activation_info_file, app_info_label);
+ }
+
+ ret = chmod(activation_info_file, 0755);
+ if(ret < 0) {
+ _LOGE("chmod[%s] fail",activation_info_file);
+ return PMINFO_R_ERROR;
+ }
+ ret = chown(activation_info_file, 5000, 5000);
+ if(ret < 0) {
+ _LOGE("chmod[%s] fail",activation_info_file);
+ return PMINFO_R_ERROR;
+ }
+ } else {
+ (void)remove(activation_info_file);
+ }
+ return PMINFO_R_OK;
+}
+
+gboolean queue_job(void *data)
+{
+ /* _LOGD("queue_job start"); */
+ pm_dbus_msg *item;
+ backend_info *ptr = NULL;
+ ptr = begin;
+ int x = 0;
+ pkgmgrinfo_pkginfo_h handle;
+ char old_zone[MAX_ZONE_NAME_LEN] = {'\0',};
+
+ /* Pop a job from queue */
+pop:
+ if (!__is_backend_busy(pos % num_of_backends)) {
+ item = _pm_queue_pop(pos % num_of_backends);
+ pos = (pos + 1) % num_of_backends;
+ }
+ else {
+ pos = (pos + 1) % num_of_backends;
+ goto pop;
+ }
+
+ int ret = 0;
+ char *backend_cmd = NULL;
+ char **args_vector = NULL;
+
+ /* queue is empty and backend process is not running */
+ if ( (item == NULL) || (item->req_type == -1) ) {
+ if(item)
+ free(item);
+ goto pop;
+ }
+ __set_backend_busy((pos + num_of_backends - 1) % num_of_backends);
+ __set_recovery_mode(item->pkgid, item->pkg_type, item->zone);
+
+ /* fork */
+ x = (pos + num_of_backends - 1) % num_of_backends;
+ strncpy((ptr + x)->pkgtype, item->pkg_type, MAX_PKG_TYPE_LEN-1);
+ strncpy((ptr + x)->backend_installer, item->backend_installer, MAX_PKG_TYPE_LEN-1);
+ strncpy((ptr + x)->pkgid, item->pkgid, MAX_PKG_PATH_LEN-1);
+ strncpy((ptr + x)->args, item->args, MAX_PKG_ARGS_LEN-1);
+#ifdef _APPFW_FEATURE_EXPANSION_PKG_INSTALL
+ strncpy((ptr + x)->tep_path, item->tep_path, MAX_PKG_PATH_LEN-1);
+#endif
+
+ if (strlen(item->zone)) {
+ strncpy((ptr + x)->zone, item->zone, MAX_ZONE_NAME_LEN-1);
+ _LOGD("target zone(%s, %s)", item->zone, (ptr + x)->zone);
+ }
+
+ (ptr + x)->pid = fork();
+ _LOGD("child forked [%d] for request type [%d]", (ptr + x)->pid, item->req_type);
+
+ switch ((ptr + x)->pid) {
+ case 0: /* child */
+ if (strlen(item->zone) && strcmp(item->zone, ZONE_HOST) != 0) {
+ if (pkgmgrinfo_pkginfo_set_zone(item->zone, old_zone,
+ sizeof(old_zone)-1) < 0) {
+ _LOGE("pkgmgrinfo_pkginfo_set_zone failed," \
+ "zone(%s)", item->zone);
+ exit(1);
+ }
+ }
+
+ switch (item->req_type) {
+ case COMM_REQ_TO_INSTALL:
+ _LOGD("before run _get_backend_path(%s)", item->backend_installer);
+ backend_cmd = _get_backend_cmd(item->backend_installer);
+ if (NULL == backend_cmd) {
+ backend_cmd = _get_backend_cmd(item->pkg_type);
+
+ if (NULL == backend_cmd) {
+ _LOGE("_get_backend_cmd failed");
+ exit(1);
+ }
+ }
+
+ _LOGD("Try to exec [%s][%s]", item->pkg_type, backend_cmd);
+ fprintf(stdout, "Try to exec [%s][%s]\n", item->pkg_type, backend_cmd);
+
+ args_vector = __generate_argv(item->args);
+ args_vector[0] = backend_cmd;
+
+ /* Execute backend !!! */
+ __exec_with_arg_vector(backend_cmd, args_vector, item->zone);
+ free(backend_cmd);
+ break;
+ case COMM_REQ_TO_UNINSTALL:
+ args_vector = __generate_argv(item->args);
+
+ _LOGD("Try to exec [%s][%s]", item->pkg_type, args_vector[0]);
+ fprintf(stdout, "Try to exec [%s][%s]\n", item->pkg_type, args_vector[0]);
+
+ /* Execute backend !!! */
+ __exec_with_arg_vector(args_vector[0], args_vector, item->zone);
+ case COMM_REQ_ACTIVATE_PKG:
+ _LOGE("ACTIVATE_PKG start [pkgid = %s]",item->pkgid);
+
+ __pm_send_signal(PKGMGR_INSTALLER_INSTALL_EVENT_STR, item->pkg_type, item->pkgid, PKGMGR_INSTALLER_START_KEY_STR, PKGMGR_INSTALLER_INSTALL_EVENT_STR, item->zone);
+
+ ret = zone_pkgmgr_parser_enable_pkg(item->pkgid, NULL, item->zone);
+ if (ret < 0) {
+ __pm_send_signal(PKGMGR_INSTALLER_INSTALL_EVENT_STR, item->pkg_type, item->pkgid, PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_FAIL_EVENT_STR, item->zone);
+ _LOGE("COMM_REQ_TO_ACTIVATOR failed");
+ exit(1);
+ }
+ __pm_send_signal(PKGMGR_INSTALLER_INSTALL_EVENT_STR, item->pkg_type, item->pkgid, PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_OK_EVENT_STR, item->zone);
+
+ _LOGE("ACTIVATE_PKG end [pkgid = %s, ret = %d]",item->pkgid, ret);
+ break;
+ case COMM_REQ_DEACTIVATE_PKG:
+ _LOGE("DEACTIVATE_PKG start [pkgid = %s]",item->pkgid);
+
+ __terminate_running_app(item->pkgid);
+
+ __pm_send_signal(PKGMGR_INSTALLER_UNINSTALL_EVENT_STR, item->pkg_type, item->pkgid, PKGMGR_INSTALLER_START_KEY_STR, PKGMGR_INSTALLER_UNINSTALL_EVENT_STR, item->zone);
+
+ /*listener need 100ms sleep to get pkginfo */
+ usleep(100 * 1000);
+ ret = zone_pkgmgr_parser_disable_pkg(item->pkgid, NULL, item->zone);
+ if (ret < 0) {
+ __pm_send_signal(PKGMGR_INSTALLER_UNINSTALL_EVENT_STR, item->pkg_type, item->pkgid, PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_FAIL_EVENT_STR, item->zone);
+ _LOGE("COMM_REQ_DEACTIVATE_PKG failed");
+ exit(1);
+ }
+ __pm_send_signal(PKGMGR_INSTALLER_UNINSTALL_EVENT_STR, item->pkg_type, item->pkgid, PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_OK_EVENT_STR, item->zone);
+
+ _LOGE("DEACTIVATE_PKG end [pkgid = %s, ret = %d]",item->pkgid, ret);
+ break;
+ case COMM_REQ_ACTIVATE_APP:
+ _LOGE("ACTIVATE_APP [appid = %s]",item->pkgid);
+
+ ret = __zone_set_activation_info(item->pkgid, 1, NULL, item->zone);
+
+ __change_item_info(item);
+
+ __pm_send_signal(PKGMGR_INSTALLER_UPGRADE_EVENT_STR, item->pkg_type, item->pkgid, PKGMGR_INSTALLER_START_KEY_STR, PKGMGR_INSTALLER_UPGRADE_EVENT_STR, item->zone);
+ if (ret != PMINFO_R_OK) {
+ __pm_send_signal(PKGMGR_INSTALLER_UPGRADE_EVENT_STR, item->pkg_type, item->pkgid, PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_FAIL_EVENT_STR, item->zone);
+ _LOGE("COMM_REQ_ACTIVATE_APP failed");
+ exit(1);
+ }
+ __pm_send_signal(PKGMGR_INSTALLER_UPGRADE_EVENT_STR, item->pkg_type, item->pkgid, PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_OK_EVENT_STR, item->zone);
+
+ _LOGE("ACTIVATE_APP end [pkgid = %s, ret = %d]",item->pkgid, ret);
+ break;
+ case COMM_REQ_DEACTIVATE_APP:
+ _LOGE("DEACTIVATE_APP [appid = %s]",item->pkgid);
+
+ ret = __zone_set_activation_info(item->pkgid, 0, NULL, item->zone);
+
+ __change_item_info(item);
+
+ __pm_send_signal(PKGMGR_INSTALLER_UPGRADE_EVENT_STR, item->pkg_type, item->pkgid, PKGMGR_INSTALLER_START_KEY_STR, PKGMGR_INSTALLER_UPGRADE_EVENT_STR, item->zone);
+ if (ret != PMINFO_R_OK) {
+ __pm_send_signal(PKGMGR_INSTALLER_UPGRADE_EVENT_STR, item->pkg_type, item->pkgid, PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_FAIL_EVENT_STR, item->zone);
+ _LOGE("COMM_REQ_ACTIVATE_APP failed");
+ exit(1);
+ }
+ __pm_send_signal(PKGMGR_INSTALLER_UPGRADE_EVENT_STR, item->pkg_type, item->pkgid, PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_OK_EVENT_STR, item->zone);
+
+ _LOGE("DEACTIVATE_APP end [pkgid = %s, ret = %d]",item->pkgid, ret);
+ break;
+ case COMM_REQ_ENABLE_BG_OPERATION:
+ ret = zone_pkgmgr_parser_set_app_background_operation(item->pkgid, FALSE, item->zone);
+
+ __change_item_info(item);
+
+ __pm_send_sub_signal(PKGMGR_INSTALLER_UPGRADE_EVENT_STR, item->pkg_type, item->pkgid, PKGMGR_INSTALLER_START_KEY_STR, PKGMGR_INSTALLER_UPGRADE_EVENT_STR, item->zone);
+ if (ret != PMINFO_R_OK) {
+ __pm_send_sub_signal(PKGMGR_INSTALLER_UPGRADE_EVENT_STR, item->pkg_type, item->pkgid, PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_FAIL_EVENT_STR, item->zone);
+ _LOGE("COMM_REQ_ENABLE_BG_OPERATION failed");
+ exit(1);
+ }
+ __pm_send_sub_signal(PKGMGR_INSTALLER_UPGRADE_EVENT_STR, item->pkg_type, item->pkgid, PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_OK_EVENT_STR, item->zone);
+
+ break;
+ case COMM_REQ_DISABLE_BG_OPERATION:
+ ret = zone_pkgmgr_parser_set_app_background_operation(item->pkgid, TRUE, item->zone);
+
+ __change_item_info(item);
+
+ __pm_send_sub_signal(PKGMGR_INSTALLER_UPGRADE_EVENT_STR, item->pkg_type, item->pkgid, PKGMGR_INSTALLER_START_KEY_STR, PKGMGR_INSTALLER_UPGRADE_EVENT_STR, item->zone);
+ if (ret != PMINFO_R_OK) {
+ __pm_send_sub_signal(PKGMGR_INSTALLER_UPGRADE_EVENT_STR, item->pkg_type, item->pkgid, PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_FAIL_EVENT_STR, item->zone);
+ _LOGE("COMM_REQ_DISABLE_BG_OPERATION failed");
+ exit(1);
+ }
+ __pm_send_sub_signal(PKGMGR_INSTALLER_UPGRADE_EVENT_STR, item->pkg_type, item->pkgid, PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_OK_EVENT_STR, item->zone);
+
+ break;
+ case COMM_REQ_ACTIVATE_APP_WITH_LABEL:
+ _LOGE("ACTIVATE_APP_WITH_LABEL [appid = %s, label = %s]",item->pkgid, item->args);
+
+ __zone_set_activation_info(item->pkgid, 1, item->args, item->zone);
+
+ __change_item_info(item);
+
+ __pm_send_signal(PKGMGR_INSTALLER_UPGRADE_EVENT_STR, item->pkg_type, item->pkgid, PKGMGR_INSTALLER_START_KEY_STR, PKGMGR_INSTALLER_UPGRADE_EVENT_STR, item->zone);
+ if (ret != PMINFO_R_OK) {
+ __pm_send_signal(PKGMGR_INSTALLER_UPGRADE_EVENT_STR, item->pkg_type, item->pkgid, PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_FAIL_EVENT_STR, item->zone);
+ _LOGE("COMM_REQ_TO_ACTIVATOR failed");
+ exit(1);
+ }
+ __pm_send_signal(PKGMGR_INSTALLER_UPGRADE_EVENT_STR, item->pkg_type, item->pkgid, PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_OK_EVENT_STR, item->zone);
+
+ _LOGE("ACTIVATE_APP_WITH_LABEL end [pkgid = %s, ret = %d]",item->pkgid, ret);
+ break;
+ case COMM_REQ_TO_MOVER:
+ case COMM_REQ_TO_CLEARER:
+ args_vector = __generate_argv(item->args);
+
+ _LOGD("Try to exec [%s][%s]", item->pkg_type, args_vector[0]);
+ fprintf(stdout, "Try to exec [%s][%s]\n", item->pkg_type, args_vector[0]);
+
+ /* Execute backend !!! */
+ __exec_with_arg_vector(args_vector[0], args_vector, item->zone);
+ break;
+ case COMM_REQ_GET_SIZE:
+ __exec_with_arg_vector("usr/bin/pkg_getsize", __generate_argv(item->args), item->zone);
+ break;
+
+ case COMM_REQ_KILL_APP:
+ case COMM_REQ_CHECK_APP:
+ _LOGD("kill/check request");
+
+ checkapp_data_s kc_data = {NULL, NULL};
+ char *sub_cmd = NULL;
+ void *checkapp_user_data = NULL;
+
+ ret = pkgmgrinfo_pkginfo_get_pkginfo(item->pkgid, &handle);
+ if (ret < 0) {
+ _LOGE("Failed to get handle");
+ exit(1);
+ }
+ if (item->req_type == COMM_REQ_KILL_APP) {
+ kc_data.zone_name = item->zone;
+ kc_data.sub_cmd = strdup("kill");
+ sub_cmd = kc_data.sub_cmd;
+ checkapp_user_data = (void *)&kc_data;
+ if (!sub_cmd) {
+ _LOGE("out_of_memory");
+ exit(1);
+ }
+
+ ret = pkgmgrinfo_appinfo_get_list(handle, PMINFO_UI_APP,
+ __pkgcmd_app_cb, checkapp_user_data);
+ if (ret < 0) {
+ _LOGE("pkgmgrinfo_appinfo_get_list() failed");
+ pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+ free(sub_cmd);
+ exit(1);
+ }
+ } else if (item->req_type == COMM_REQ_CHECK_APP) {
+ kc_data.zone_name = item->zone;
+ kc_data.sub_cmd = strdup("check");
+ sub_cmd = kc_data.sub_cmd;
+ checkapp_user_data = (void *)&kc_data;
+ if (!sub_cmd) {
+ _LOGE("out_of_memory");
+ exit(1);
+ }
+
+ ret = pkgmgrinfo_appinfo_get_list(handle, PMINFO_UI_APP,
+ __pkgcmd_app_cb, checkapp_user_data);
+ if (ret < 0) {
+ _LOGE("pkgmgrinfo_appinfo_get_list() failed");
+ pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+ free(sub_cmd);
+ exit(1);
+ }
+ }
+ pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+ break;
+
+ case COMM_REQ_CLEAR_CACHE_DIR:
+ __exec_with_arg_vector("/usr/bin/pkg_clearcache", __generate_argv(item->pkgid), item->zone);
+ break;
+
+ case COMM_REQ_MAKE_EXTERNAL_DIR:
+ __exec_with_arg_vector("/usr/bin/pkg_mkext", NULL, item->zone);
+ break;
+ }
+ /* exit child */
+ exit(0);
+ break;
+
+ case -1: /* error */
+ fprintf(stderr, "Fail to execute fork()\n");
+ exit(1);
+ break;
+
+ default: /* parent */
+ _LOGD("parent exit");
+ break;
+ }
+
+ free(item);
+
+ return FALSE;
+}
+
+void _app_str_trim(char *input)
+{
+ char *trim_str = input;
+
+ if (input == NULL)
+ return;
+
+ while (*input != 0) {
+ if (!IS_WHITESPACE(*input)) {
+ *trim_str = *input;
+ trim_str++;
+ }
+ input++;
+ }
+
+ *trim_str = 0;
+ return;
+}
+
+char *_get_backend_cmd(char *type)
+{
+ FILE *fp = NULL;
+ char buffer[1024] = { 0 };
+ char *command = NULL;
+ int size = 0;
+ fp = fopen(PKG_CONF_PATH, "r");
+ if (fp == NULL) {
+ return NULL;
+ }
+
+ char *path = NULL;
+ while (fgets(buffer, 1024, fp) != NULL) {
+ if (buffer[0] == '#')
+ continue;
+
+ _app_str_trim(buffer);
+
+ if ((path = strstr(buffer, PKG_BACKEND)) != NULL) {
+// _LOGD("buffer [%s]", buffer);
+ path = path + strlen(PKG_BACKEND);
+// _LOGD("path [%s]", path);
+
+ command = (char *)malloc(sizeof(char) * strlen(path) + strlen(type) + 1);
+ if (command == NULL) {
+ fclose(fp);
+ _LOGE("command is null for [path=%s, type=%s]", path, type);
+ return NULL;
+ }
+
+ size = strlen(path) + strlen(type) + 1;
+ snprintf(command, size, "%s%s", path, type);
+ command[strlen(path) + strlen(type)] = '\0';
+// _LOGD("command [%s]", command);
+
+ if (fp != NULL)
+ fclose(fp);
+
+ return command;
+ }
+
+ memset(buffer, 0x00, 1024);
+ }
+
+ if (fp != NULL)
+ fclose(fp);
+
+ return NULL; /* cannot find proper command */
+}
+
+int main(int argc, char *argv[])
+{
+ backend_info *ptr = NULL;
+ int r;
+
+ _LOGE("package manager server start");
+
+ r = _pm_queue_init();
+ if (r) {
+ _LOGE("Queue Initialization Failed\n");
+ return -1;
+ }
+
+ /*Allocate memory for holding pid, pkgtype and pkgid*/
+ ptr = (backend_info*)calloc(num_of_backends, sizeof(backend_info));
+ if (ptr == NULL) {
+ _LOGD("Malloc Failed\n");
+ return -1;
+ }
+ memset(ptr, '\0', num_of_backends * sizeof(backend_info));
+ begin = ptr;
+
+#if (GLIB_MAJOR_VERSION <= 2 && GLIB_MINOR_VERSION < 36)
+ g_type_init();
+#endif
+ mainloop = g_main_loop_new(NULL, FALSE);
+ if (!mainloop){
+ _LOGE("g_main_loop_new failed\n");
+ return -1;
+ }
+
+ pkgmgr_server_gdbus_h pkg_mgr;
+ r = pkg_mgr_server_gdbus_init(&pkg_mgr);
+ if (r) {
+ _LOGE("gdbus_init failed\n");
+ return -1;
+ }
+
+ // register callback
+ pkg_mgr_set_request_callback(pkg_mgr, req_cb, NULL);
+
+#ifdef _APPFW_FEATURE_EXPANSION_PKG_INSTALL
+ pkg_mgr_set_request_tep_callback(pkg_mgr, req_tep_cb, NULL);
+#endif
+
+ pkg_mgr_set_callback_to_create_directory(pkg_mgr, create_external_dir_cb);
+#ifdef _APPFW_FEATURE_DRM_ENABLE
+ pkg_mgr_set_drm_generate_license_request_callback(pkg_mgr, gen_license_req_cb);
+ pkg_mgr_set_drm_register_license_callback(pkg_mgr, reg_license_cb);
+ pkg_mgr_set_drm_decrypt_package_callback(pkg_mgr, decrypt_pkg_cb);
+#endif
+
+ g_main_loop_run(mainloop);
+ _pm_queue_final();
+ /*Free backend info */
+ if (begin) {
+ free(begin);
+ begin = NULL;
+ }
+ pkg_mgr_server_gdbus_fini(pkg_mgr);
+
+ _LOGE("package manager server terminated.");
+
+ return 0;
+}