4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>,
7 * Jaeho Lee <jaeho81.lee@samsung.com>, Shobhit Srivastava <shobhit.s@samsung.com>
9 * Licensed under the Apache License, Version 2.0 (the "License");
10 * you may not use this file except in compliance with the License.
11 * You may obtain a copy of the License at
13 * http://www.apache.org/licenses/LICENSE-2.0
15 * Unless required by applicable law or agreed to in writing, software
16 * distributed under the License is distributed on an "AS IS" BASIS,
17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
29 #include <sys/types.h>
33 #include <sys/types.h>
41 #include <pkgmgr-info.h>
42 #include <pkgmgr/pkgmgr_parser_db.h>
43 #include <tzplatform_config.h>
44 #include <drm-tizen-apps.h>
46 #include "pkgmgr_installer.h"
47 #include "pkgmgr-server.h"
49 #include "package-manager.h"
52 #define NO_MATCHING_FILE 11
55 #define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
57 #define EXT_STORAGE_GROUP 10001
58 #define EXT_STORAGE_APPDATA_GROUP 10002
59 #define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
69 8 bit value to represent maximum 8 backends.
70 Each bit position corresponds to a queue slot which
71 is dynamically determined.
73 char backend_busy = 0;
74 extern int num_of_backends;
76 struct signal_info_t {
81 static int pipe_sig[2];
82 static GIOChannel *pipe_io;
83 static guint pipe_wid;
86 extern queue_info_map *start;
89 GMainLoop *mainloop = NULL;
94 OPERATION_INSTALL = 0,
101 static int __check_backend_status_for_exit(void);
102 static int __check_queue_status_for_exit(void);
103 static int __is_backend_busy(int position);
104 static void __set_backend_busy(int position);
105 static void __set_backend_free(int position);
106 static void sighandler(int signo);
108 gboolean exit_server(void *data);
110 /* To check whether a particular backend is free/busy*/
111 static int __is_backend_busy(int position)
113 return backend_busy & 1<<position;
115 /*To set a particular backend as busy*/
116 static void __set_backend_busy(int position)
118 backend_busy = backend_busy | 1<<position;
120 /*To set a particular backend as free */
121 static void __set_backend_free(int position)
123 backend_busy = backend_busy & ~(1<<position);
126 static void __send_app_signal(uid_t uid, const char *req_id,
127 const char *pkgid, const char *appid,
128 const char *key, const char *val, int req_type)
130 pkgmgr_installer *pi;
132 pi = pkgmgr_installer_new();
134 DBG("Failure in creating the pkgmgr_installer object");
138 if (pkgmgr_installer_set_uid(pi, uid))
142 case PKGMGR_REQUEST_TYPE_ENABLE_GLOBAL_APP_FOR_UID:
143 case PKGMGR_REQUEST_TYPE_ENABLE_APP:
144 if (pkgmgr_installer_set_request_type(pi, PKGMGR_REQ_ENABLE_APP))
147 case PKGMGR_REQUEST_TYPE_DISABLE_GLOBAL_APP_FOR_UID:
148 case PKGMGR_REQUEST_TYPE_DISABLE_APP:
149 if (pkgmgr_installer_set_request_type(pi, PKGMGR_REQ_DISABLE_APP))
152 case PKGMGR_REQUEST_TYPE_ENABLE_APP_SPLASH_SCREEN:
153 if (pkgmgr_installer_set_request_type(pi, PKGMGR_REQ_ENABLE_APP_SPLASH_SCREEN))
156 case PKGMGR_REQUEST_TYPE_DISABLE_APP_SPLASH_SCREEN:
157 if (pkgmgr_installer_set_request_type(pi, PKGMGR_REQ_DISABLE_APP_SPLASH_SCREEN))
161 DBG("Unsupported req_type[%d]", req_type);
165 if (pkgmgr_installer_set_session_id(pi, req_id))
167 pkgmgr_installer_send_app_signal(pi, "app", pkgid, appid, key, val);
170 pkgmgr_installer_free(pi);
175 static void send_fail_signal(char *pname, char *ptype, char *args)
177 DBG("send_fail_signal start\n");
182 pkgmgr_installer *pi;
183 pi = pkgmgr_installer_new();
185 DBG("Failure in creating the pkgmgr_installer object");
188 ret_parse = g_shell_parse_argv(args,
189 &argcp, &argvp, &gerr);
190 if (FALSE == ret_parse) {
191 DBG("Failed to split args: %s", args);
192 DBG("messsage: %s", gerr->message);
193 pkgmgr_installer_free(pi);
197 pkgmgr_installer_receive_request(pi, argcp, argvp);
198 pkgmgr_installer_send_signal(pi, ptype, pname, "end", "fail");
199 pkgmgr_installer_free(pi);
203 static gboolean pipe_io_handler(GIOChannel *io, GIOCondition cond, gpointer data)
209 struct signal_info_t info;
210 backend_info *ptr = begin;
212 s = g_io_channel_read_chars(io, (gchar *)&info, sizeof(struct signal_info_t), &len, &err);
213 if (s != G_IO_STATUS_NORMAL) {
214 ERR("Signal pipe read failed: %s", err->message);
219 for (x = 0; x < num_of_backends; x++, ptr++) {
220 if (ptr && ptr->pid == info.pid)
224 if (x == num_of_backends) {
225 ERR("Unknown child exit");
229 __set_backend_free(x);
230 if (WIFSIGNALED(info.status) || WEXITSTATUS(info.status)) {
231 send_fail_signal(ptr->pkgid, ptr->pkgtype, ptr->args);
232 DBG("backend[%s] exit with error", ptr->pkgtype);
234 DBG("backend[%s] exit", ptr->pkgtype);
237 g_idle_add(queue_job, NULL);
242 static int __init_backend_info(void)
246 /*Allocate memory for holding pid, pkgtype and pkgid*/
247 ptr = (backend_info*)calloc(num_of_backends, sizeof(backend_info));
249 DBG("Malloc Failed\n");
254 if (pipe(pipe_sig)) {
255 ERR("create pipe failed");
259 pipe_io = g_io_channel_unix_new(pipe_sig[0]);
260 g_io_channel_set_encoding(pipe_io, NULL, NULL);
261 g_io_channel_set_buffered(pipe_io, FALSE);
262 pipe_wid = g_io_add_watch(pipe_io, G_IO_IN, pipe_io_handler, NULL);
267 static void __fini_backend_info(void)
269 g_source_remove(pipe_wid);
270 g_io_channel_unref(pipe_io);
274 /*Free backend info */
278 static void sighandler(int signo)
280 struct signal_info_t info;
281 char buf[1024] = {0, };
283 info.pid = waitpid(-1, &info.status, WNOHANG);
284 if (write(pipe_sig[1], &info, sizeof(struct signal_info_t)) < 0)
285 ERR("failed to write result: %s", strerror_r(errno, buf, sizeof(buf)));
288 static int __register_signal_handler(void)
290 static int sig_reg = 0;
291 struct sigaction act;
296 act.sa_handler = sighandler;
297 sigemptyset(&act.sa_mask);
298 act.sa_flags = SA_NOCLDSTOP;
299 if (sigaction(SIGCHLD, &act, NULL) < 0) {
300 ERR("signal: SIGCHLD failed\n");
304 g_timeout_add_seconds(2, exit_server, NULL);
310 static int __check_backend_status_for_exit(void)
313 for(i = 0; i < num_of_backends; i++)
315 if (!__is_backend_busy(i))
323 static int __check_queue_status_for_exit(void)
325 pm_queue_data *head[MAX_QUEUE_NUM] = {NULL,};
326 queue_info_map *ptr = NULL;
331 for(i = 0; i < entries; i++)
333 if (ptr->queue_slot <= slot) {
339 slot = ptr->queue_slot;
344 for(i = 0; i < num_of_backends; i++)
354 gboolean exit_server(void *data)
356 DBG("exit_server Start\n");
357 if (__check_backend_status_for_exit() &&
358 __check_queue_status_for_exit()) {
359 if (!getenv("PMS_STANDALONE")) {
360 g_main_loop_quit(mainloop);
367 static int __pkgcmd_read_proc(const char *path, char *buf, int size)
371 if (buf == NULL || path == NULL)
373 fd = open(path, O_RDONLY);
376 ret = read(fd, buf, size - 1);
386 static int __pkgcmd_find_pid_by_cmdline(const char *dname,
387 const char *cmdline, const char *apppath)
391 if (strcmp(cmdline, apppath) == 0) {
393 if (pid != getpgid(pid))
399 static int __pkgcmd_proc_iter_kill_cmdline(const char *apppath, int option)
402 struct dirent dentry, *result;
405 char buf[1024] = {'\0'};
408 dp = opendir("/proc");
413 for (ret = readdir_r(dp, &dentry, &result);
414 ret == 0 && result != NULL;
415 ret = readdir_r(dp, &dentry, &result)) {
416 if (!isdigit(dentry.d_name[0]))
419 snprintf(buf, sizeof(buf), "/proc/%s/cmdline", dentry.d_name);
420 ret = __pkgcmd_read_proc(buf, buf, sizeof(buf));
424 pid = __pkgcmd_find_pid_by_cmdline(dentry.d_name, buf, apppath);
435 if (killpg(pgid, SIGKILL) < 0) {
447 static void __make_pid_info_file(char *req_key, int pid)
451 char buf[MAX_PKG_TYPE_LEN] = {0};
452 char info_file[PATH_MAX] = {'\0'};
457 snprintf(info_file, PATH_MAX, "/tmp/pkgmgr/%s", req_key);
459 DBG("info_path(%s)", info_file);
460 file = fopen(info_file, "w");
462 ERR("Couldn't open the file(%s)", info_file);
466 snprintf(buf, MAX_PKG_TYPE_LEN, "%d\n", pid);
467 fwrite(buf, 1, strlen(buf), file);
475 static int __kill_app(char *appid, uid_t uid)
477 pkgmgrinfo_appinfo_h appinfo;
478 int ret = PMINFO_R_ERROR;
481 ret = pkgmgrinfo_appinfo_get_usr_appinfo(appid, uid, &appinfo);
482 if (ret != PMINFO_R_OK)
483 return PMINFO_R_ERROR;
485 ret = pkgmgrinfo_appinfo_get_exec(appinfo, &exec);
486 if (ret != PMINFO_R_OK) {
487 pkgmgrinfo_appinfo_destroy_appinfo(appinfo);
488 return PMINFO_R_ERROR;
491 ret = __pkgcmd_proc_iter_kill_cmdline(exec, 1);
492 if (ret != PMINFO_R_OK) {
493 DBG("failed to kill app[%s], exec[%s]", appid, exec);
496 pkgmgrinfo_appinfo_destroy_appinfo(appinfo);
500 static int __pkgcmd_app_cb(const pkgmgrinfo_appinfo_h handle, void *user_data)
507 if (handle == NULL) {
508 perror("appinfo handle is NULL\n");
511 ret = pkgmgrinfo_appinfo_get_exec(handle, &exec);
513 perror("Failed to get app exec path\n");
516 ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid);
518 perror("Failed to get pkgid\n");
522 if (strcmp(user_data, "kill") == 0)
523 pid = __pkgcmd_proc_iter_kill_cmdline(exec, 1);
524 else if(strcmp(user_data, "check") == 0)
525 pid = __pkgcmd_proc_iter_kill_cmdline(exec, 0);
527 __make_pid_info_file(pkgid, pid);
532 void free_user_context(user_ctx* ctx)
539 //env variable ends by NULL element
549 int set_environement(user_ctx *ctx)
554 gid_t groups[] = {EXT_STORAGE_GROUP, EXT_STORAGE_APPDATA_GROUP};
558 if (setgid(ctx->gid)) {
559 ERR("setgid failed: %d", errno);
562 if (setgroups(ARRAY_SIZE(groups), groups) < 0) {
563 ERR("setgroups failed: %d", errno);
566 if (setuid(ctx->uid)) {
567 ERR("setuid failed: %d", errno);
571 //env variable ends by NULL element
573 if (putenv(env[i]) != 0)
580 user_ctx *get_user_context(uid_t uid)
582 /* we can use getpwnam because this is used only after a
583 * fork and just before an execv
584 * No concurrencial call can corrupt the data
585 * returned by getpwuid
587 user_ctx *context_res;
589 char buf[1024] = {0, };
590 struct passwd pwd, *result;
595 ret = getpwuid_r(uid, &pwd, buf, sizeof(buf), &result);
596 if (ret != 0 || result == NULL)
600 context_res = (user_ctx *)malloc(sizeof(user_ctx));
605 env = (char **)malloc(3 * sizeof(char *));
610 // Build environment context
611 len = snprintf(NULL, 0, "HOME=%s", pwd.pw_dir);
612 env[0] = (char *)malloc((len + 1) * sizeof(char));
617 snprintf(env[0], len + 1, "HOME=%s", pwd.pw_dir);
618 len = snprintf(NULL, 0, "USER=%s", pwd.pw_name);
619 env[1] = (char *)malloc((len + 1) * sizeof(char));
624 snprintf(env[1], len + 1, "USER=%s", pwd.pw_name);
632 //env variable ends by NULL element
633 while (env && env[i]) {
640 context_res->env = env;
641 context_res->uid = uid;
642 context_res->gid = pwd.pw_gid;
647 static char **__generate_argv(const char *args)
649 /* Create args vector
650 * req_id + pkgid + args
652 * vector size = # of args +
653 *(req_id + pkgid + NULL termination = 3)
654 * Last value must be NULL for execv.
662 ret_parse = g_shell_parse_argv(args, &argcp, &argvp, &gerr);
663 if (FALSE == ret_parse) {
664 DBG("Failed to split args: %s", args);
665 DBG("messsage: %s", gerr->message);
670 for (i = 0; i < argcp; i++)
671 DBG(">>>>>> argsv[%d]=%s", i, argvp[i]);
676 void __set_environment(gpointer user_data)
678 user_ctx *ctx = (user_ctx *)user_data;
680 if (set_environement(ctx))
681 DBG("Failed to set env for the user : %d", ctx->uid);
684 static int __fork_and_exec_with_args(char **argv, uid_t uid)
686 user_ctx* user_context;
687 GError *error = NULL;
691 user_context = get_user_context(uid);
693 DBG("Failed to getenv for the user : %d", uid);
697 ret = g_spawn_async(NULL, argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD,
698 __set_environment, (gpointer)user_context, &pid,
701 ERR("Failed to excute backend: %s", error->message);
705 free_user_context(user_context);
710 static int __change_item_info(pm_dbus_msg *item, uid_t uid, bool *is_global)
714 pkgmgrinfo_appinfo_h handle = NULL;
716 switch (item->req_type) {
717 case PKGMGR_REQUEST_TYPE_DISABLE_APP:
718 case PKGMGR_REQUEST_TYPE_DISABLE_GLOBAL_APP_FOR_UID:
719 case PKGMGR_REQUEST_TYPE_ENABLE_APP_SPLASH_SCREEN:
720 case PKGMGR_REQUEST_TYPE_DISABLE_APP_SPLASH_SCREEN:
721 ret = pkgmgrinfo_appinfo_get_usr_appinfo(item->pkgid, uid, &handle);
723 case PKGMGR_REQUEST_TYPE_ENABLE_APP:
724 case PKGMGR_REQUEST_TYPE_ENABLE_GLOBAL_APP_FOR_UID:
725 ret = pkgmgrinfo_appinfo_get_usr_disabled_appinfo(item->pkgid, uid, &handle);
728 return PMINFO_R_ERROR;
731 if (ret != PMINFO_R_OK)
732 return PMINFO_R_ERROR;
734 ret = pkgmgrinfo_appinfo_is_global(handle, is_global);
735 if (ret != PMINFO_R_OK)
738 if ((item->req_type == PKGMGR_REQUEST_TYPE_DISABLE_APP
739 || item->req_type == PKGMGR_REQUEST_TYPE_ENABLE_APP)
741 ret = PMINFO_R_ERROR;
743 } else if ((item->req_type == PKGMGR_REQUEST_TYPE_DISABLE_GLOBAL_APP_FOR_UID
744 || item->req_type == PKGMGR_REQUEST_TYPE_ENABLE_GLOBAL_APP_FOR_UID)
746 ret = PMINFO_R_ERROR;
750 ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid);
751 if (ret != PMINFO_R_OK)
754 strncpy(item->appid, item->pkgid, sizeof(item->pkgid) - 1);
755 memset((item->pkgid), 0, MAX_PKG_NAME_LEN);
756 strncpy(item->pkgid, pkgid, sizeof(item->pkgid) - 1);
759 pkgmgrinfo_appinfo_destroy_appinfo(handle);
764 static int __process_install(pm_dbus_msg *item)
768 char args[MAX_PKG_ARGS_LEN] = {'\0', };
771 backend_cmd = _get_backend_cmd(item->pkg_type);
772 if (backend_cmd == NULL)
775 snprintf(args, sizeof(args), "%s -k %s -i %s %s", backend_cmd,
776 item->req_id, item->pkgid, item->args);
778 argv = __generate_argv(args);
780 pid = __fork_and_exec_with_args(argv, item->uid);
787 static int __process_mount_install(pm_dbus_msg *item)
791 char args[MAX_PKG_ARGS_LEN] = {'\0', };
794 backend_cmd = _get_backend_cmd(item->pkg_type);
795 if (backend_cmd == NULL)
798 snprintf(args, sizeof(args), "%s -k %s -w %s %s", backend_cmd,
799 item->req_id, item->pkgid, item->args);
801 argv = __generate_argv(args);
803 pid = __fork_and_exec_with_args(argv, item->uid);
810 static int __process_reinstall(pm_dbus_msg *item)
814 char args[MAX_PKG_ARGS_LEN];
817 backend_cmd = _get_backend_cmd(item->pkg_type);
818 if (backend_cmd == NULL)
821 snprintf(args, sizeof(args), "%s -k %s -r %s", backend_cmd,
822 item->req_id, item->pkgid);
823 argv = __generate_argv(args);
825 pid = __fork_and_exec_with_args(argv, item->uid);
833 static int __process_uninstall(pm_dbus_msg *item)
837 char args[MAX_PKG_ARGS_LEN];
840 backend_cmd = _get_backend_cmd(item->pkg_type);
841 if (backend_cmd == NULL)
844 snprintf(args, sizeof(args), "%s -k %s -d %s", backend_cmd,
845 item->req_id, item->pkgid);
846 argv = __generate_argv(args);
848 pid = __fork_and_exec_with_args(argv, item->uid);
856 static int __process_move(pm_dbus_msg *item)
860 char args[MAX_PKG_ARGS_LEN];
863 backend_cmd = _get_backend_cmd(item->pkg_type);
864 if (backend_cmd == NULL)
867 snprintf(args, sizeof(args), "%s -k %s -m %s -t %s", backend_cmd,
868 item->req_id, item->pkgid, item->args);
869 argv = __generate_argv(args);
871 pid = __fork_and_exec_with_args(argv, item->uid);
879 static int __process_enable_pkg(pm_dbus_msg *item)
885 static int __process_disable_pkg(pm_dbus_msg *item)
891 static int __process_enable_app(pm_dbus_msg *item)
894 bool is_global = false;
896 __send_app_signal(item->uid, item->req_id, item->pkgid, item->pkgid,
897 PKGMGR_INSTALLER_START_KEY_STR,
898 PKGMGR_INSTALLER_APP_ENABLE_EVENT_STR, item->req_type);
900 /* get actual pkgid and replace it to appid which is currently stored at pkgid variable */
901 ret = __change_item_info(item, item->uid, &is_global);
902 if (ret != PMINFO_R_OK || strlen(item->appid) == 0) {
903 __send_app_signal(item->uid, item->req_id, item->pkgid, item->pkgid,
904 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_FAIL_EVENT_STR,
909 ret = pkgmgr_parser_update_app_disable_info_in_usr_db(item->appid, item->uid, 0);
910 if (ret != PMINFO_R_OK)
911 __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
912 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_FAIL_EVENT_STR,
915 __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
916 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_OK_EVENT_STR,
923 static int __process_disable_app(pm_dbus_msg *item)
926 bool is_global = false;
928 __send_app_signal(item->uid, item->req_id, item->pkgid, item->pkgid,
929 PKGMGR_INSTALLER_START_KEY_STR,
930 PKGMGR_INSTALLER_APP_DISABLE_EVENT_STR, item->req_type);
932 /* get actual pkgid and replace it to appid which is currently stored at pkgid variable */
933 ret = __change_item_info(item, item->uid, &is_global);
934 if (ret != PMINFO_R_OK || strlen(item->appid) == 0) {
935 __send_app_signal(item->uid, item->req_id, item->pkgid, item->pkgid,
936 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_FAIL_EVENT_STR,
941 ret = __kill_app(item->appid, item->uid);
942 if (ret != PMINFO_R_OK) {
943 __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
944 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_FAIL_EVENT_STR,
948 ret = pkgmgr_parser_update_app_disable_info_in_usr_db(item->appid, item->uid, 1);
949 if (ret != PMINFO_R_OK)
950 __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
951 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_FAIL_EVENT_STR,
954 __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
955 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_OK_EVENT_STR,
961 static int __process_enable_global_app_for_uid(pm_dbus_msg *item)
964 bool is_global = true;
966 __send_app_signal(item->uid, item->req_id, item->pkgid, item->pkgid,
967 PKGMGR_INSTALLER_START_KEY_STR,
968 PKGMGR_INSTALLER_GLOBAL_APP_ENABLE_FOR_UID, item->req_type);
970 /* get actual pkgid and replace it to appid which is currently stored at pkgid variable */
971 ret = __change_item_info(item, item->uid, &is_global);
972 if (ret != PMINFO_R_OK || strlen(item->appid) == 0) {
973 __send_app_signal(item->uid, item->req_id, item->pkgid, item->pkgid,
974 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_FAIL_EVENT_STR,
979 ret = pkgmgr_parser_update_global_app_disable_for_uid_info_in_db(item->appid, item->uid, 0);
980 if (ret != PMINFO_R_OK)
981 __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
982 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_FAIL_EVENT_STR,
985 __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
986 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_OK_EVENT_STR,
992 static int __process_disable_global_app_for_uid(pm_dbus_msg *item)
995 bool is_global = true;
997 __send_app_signal(item->uid, item->req_id,
998 item->pkgid, item->pkgid,
999 PKGMGR_INSTALLER_START_KEY_STR,
1000 PKGMGR_INSTALLER_GLOBAL_APP_DISABLE_FOR_UID, item->req_type);
1002 /* get actual pkgid and replace it to appid which is currently stored at pkgid variable */
1003 ret = __change_item_info(item, GLOBAL_USER, &is_global);
1004 if (ret != PMINFO_R_OK || strlen(item->appid) == 0) {
1005 __send_app_signal(item->uid, item->req_id, item->pkgid, item->pkgid,
1006 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_FAIL_EVENT_STR,
1011 ret = __kill_app(item->appid, item->uid);
1012 ret = pkgmgr_parser_update_global_app_disable_for_uid_info_in_db(item->appid,
1015 if (ret != PMINFO_R_OK)
1016 __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
1017 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_FAIL_EVENT_STR,
1020 __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
1021 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_OK_EVENT_STR,
1027 static int __process_getsize(pm_dbus_msg *item)
1029 static const char *backend_cmd = "/usr/bin/pkg_getsize";
1031 char args[MAX_PKG_ARGS_LEN];
1034 snprintf(args, sizeof(args), "%s %s %s -k %s", backend_cmd, item->pkgid,
1035 item->args, item->req_id);
1036 argv = __generate_argv(args);
1037 pid = __fork_and_exec_with_args(argv, item->uid);
1044 static int __process_cleardata(pm_dbus_msg *item)
1048 char args[MAX_PKG_ARGS_LEN];
1051 backend_cmd = _get_backend_cmd(item->pkg_type);
1052 if (backend_cmd == NULL)
1055 /* TODO: set movetype */
1056 snprintf(args, sizeof(args), "%s -k %s -c %s", backend_cmd,
1057 item->req_id, item->pkgid);
1058 argv = __generate_argv(args);
1060 pid = __fork_and_exec_with_args(argv, item->uid);
1068 static int __process_clearcache(pm_dbus_msg *item)
1070 static const char *backend_cmd = "/usr/bin/pkg_clearcache";
1072 char args[MAX_PKG_ARGS_LEN];
1075 snprintf(args, sizeof(args), "%s %s", backend_cmd, item->pkgid);
1076 argv = __generate_argv(args);
1077 pid = __fork_and_exec_with_args(argv, item->uid);
1084 static int __process_kill(pm_dbus_msg *item)
1087 pkgmgrinfo_pkginfo_h handle;
1089 ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(item->pkgid, item->uid,
1092 ERR("Failed to get handle");
1096 ret = pkgmgrinfo_appinfo_get_usr_list(handle, PMINFO_ALL_APP,
1097 __pkgcmd_app_cb, "kill", item->uid);
1098 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1100 ERR("pkgmgrinfo_appinfo_get_list() failed");
1107 static int __process_check(pm_dbus_msg *item)
1110 pkgmgrinfo_pkginfo_h handle;
1112 ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(item->pkgid, item->uid,
1115 ERR("Failed to get handle");
1119 ret = pkgmgrinfo_appinfo_get_usr_list(handle, PMINFO_ALL_APP,
1120 __pkgcmd_app_cb, "check", item->uid);
1121 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1123 ERR("pkgmgrinfo_appinfo_get_list() failed");
1130 static int __process_generate_license_request(pm_dbus_msg *item)
1134 char req_data[MAX_PKG_ARGS_LEN];
1135 unsigned int req_data_len;
1136 char license_url[MAX_PKG_ARGS_LEN];
1137 unsigned int license_url_len;
1139 resp_data = item->args;
1140 req_data_len = sizeof(req_data);
1141 license_url_len = sizeof(license_url);
1143 ret = drm_tizen_generate_license_request(resp_data, strlen(resp_data),
1144 req_data, &req_data_len, license_url, &license_url_len);
1145 if (ret != TADC_SUCCESS) {
1146 ERR("drm_tizen_generate_license_request failed: %d", ret);
1147 __return_value_to_caller(item->req_id, g_variant_new("(iss)",
1148 PKGMGR_R_ESYSTEM, "", ""));
1152 __return_value_to_caller(item->req_id,
1153 g_variant_new("(iss)", PKGMGR_R_OK, req_data,
1159 static int __process_register_license(pm_dbus_msg *item)
1164 resp_data = item->args;
1166 ret = drm_tizen_register_license(resp_data, strlen(resp_data));
1167 if (ret != TADC_SUCCESS) {
1168 ERR("drm_tizen_register_license failed: %d", ret);
1169 __return_value_to_caller(item->req_id,
1170 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1174 __return_value_to_caller(item->req_id,
1175 g_variant_new("(i)", PKGMGR_R_OK));
1180 static int __process_decrypt_package(pm_dbus_msg *item)
1183 char *drm_file_path;
1184 char *decrypted_file_path;
1186 drm_file_path = item->pkgid;
1187 decrypted_file_path = item->args;
1189 /* TODO: check ownership of decrypted file */
1190 ret = drm_tizen_decrypt_package(drm_file_path, strlen(drm_file_path),
1191 decrypted_file_path, strlen(decrypted_file_path));
1192 if (ret != TADC_SUCCESS) {
1193 ERR("drm_tizen_register_license failed: %d", ret);
1194 __return_value_to_caller(item->req_id,
1195 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1199 __return_value_to_caller(item->req_id,
1200 g_variant_new("(i)", PKGMGR_R_OK));
1205 static int __process_update_app_splash_screen(pm_dbus_msg *item, int flag)
1208 bool is_global = false;
1211 ret = __change_item_info(item, item->uid, &is_global);
1212 if (ret != PMINFO_R_OK || strlen(item->appid) == 0)
1215 val = flag ? PKGMGR_INSTALLER_APP_ENABLE_SPLASH_SCREEN_EVENT_STR :
1216 PKGMGR_INSTALLER_APP_DISABLE_SPLASH_SCREEN_EVENT_STR;
1217 __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
1218 PKGMGR_INSTALLER_START_KEY_STR, val, item->req_type);
1221 ret = pkgmgr_parser_update_global_app_splash_screen_display_info_in_usr_db(
1222 item->appid, item->uid, flag);
1224 ret = pkgmgr_parser_update_app_splash_screen_display_info_in_usr_db(
1225 item->appid, item->uid, flag);
1226 if (ret != PMINFO_R_OK)
1227 __send_app_signal(item->uid, item->req_id, item->pkgid,
1228 item->appid, PKGMGR_INSTALLER_END_KEY_STR,
1229 PKGMGR_INSTALLER_FAIL_EVENT_STR,
1232 __send_app_signal(item->uid, item->req_id, item->pkgid,
1233 item->appid, PKGMGR_INSTALLER_END_KEY_STR,
1234 PKGMGR_INSTALLER_OK_EVENT_STR,
1240 static int __process_set_restriction_mode(pm_dbus_msg *item)
1245 mode = atoi(item->args);
1246 ret = _restriction_mode_set(item->uid, item->pkgid, mode);
1248 __return_value_to_caller(item->req_id,
1249 g_variant_new("(i)", ret));
1254 static int __process_unset_restriction_mode(pm_dbus_msg *item)
1259 mode = atoi(item->args);
1260 ret = _restriction_mode_unset(item->uid, item->pkgid, mode);
1262 __return_value_to_caller(item->req_id,
1263 g_variant_new("(i)", ret));
1268 static int __process_get_restriction_mode(pm_dbus_msg *item)
1273 ret = _restriction_mode_get(item->uid, item->pkgid, &mode);
1275 __return_value_to_caller(item->req_id,
1276 g_variant_new("(ii)", mode, ret));
1281 gboolean queue_job(void *data)
1283 pm_dbus_msg *item = NULL;
1288 /* Pop a job from queue */
1289 for (x = 0, ptr = begin; x < num_of_backends; x++, ptr++) {
1290 if (__is_backend_busy(x))
1293 item = _pm_queue_pop(x);
1294 if (item && item->req_type != -1)
1299 /* all backend messages queue are empty or busy */
1300 if (x == num_of_backends)
1303 /*save pkg type and pkg name for future*/
1304 strncpy(ptr->pkgtype, item->pkg_type, MAX_PKG_TYPE_LEN-1);
1305 strncpy(ptr->pkgid, item->pkgid, MAX_PKG_NAME_LEN-1);
1306 strncpy(ptr->args, item->args, MAX_PKG_ARGS_LEN-1);
1307 memset((item->appid),0,MAX_PKG_NAME_LEN);
1308 ptr->uid = item->uid;
1309 DBG("handle request type [%d]", item->req_type);
1311 switch (item->req_type) {
1312 case PKGMGR_REQUEST_TYPE_INSTALL:
1313 __set_backend_busy(x);
1314 ret = __process_install(item);
1316 case PKGMGR_REQUEST_TYPE_MOUNT_INSTALL:
1317 __set_backend_busy(x);
1318 ret = __process_mount_install(item);
1320 case PKGMGR_REQUEST_TYPE_REINSTALL:
1321 __set_backend_busy(x);
1322 ret = __process_reinstall(item);
1324 case PKGMGR_REQUEST_TYPE_UNINSTALL:
1325 __set_backend_busy(x);
1326 ret = __process_uninstall(item);
1328 case PKGMGR_REQUEST_TYPE_MOVE:
1329 __set_backend_busy(x);
1330 ret = __process_move(item);
1332 case PKGMGR_REQUEST_TYPE_ENABLE_PKG:
1333 ret = __process_enable_pkg(item);
1335 case PKGMGR_REQUEST_TYPE_DISABLE_PKG:
1336 ret = __process_disable_pkg(item);
1338 case PKGMGR_REQUEST_TYPE_ENABLE_APP:
1339 ret = __process_enable_app(item);
1341 case PKGMGR_REQUEST_TYPE_DISABLE_APP:
1342 ret = __process_disable_app(item);
1344 case PKGMGR_REQUEST_TYPE_GETSIZE:
1345 __set_backend_busy(x);
1346 ret = __process_getsize(item);
1348 case PKGMGR_REQUEST_TYPE_CLEARDATA:
1349 __set_backend_busy(x);
1350 ret = __process_cleardata(item);
1352 case PKGMGR_REQUEST_TYPE_CLEARCACHE:
1353 __set_backend_busy(x);
1354 ret = __process_clearcache(item);
1356 case PKGMGR_REQUEST_TYPE_ENABLE_GLOBAL_APP_FOR_UID:
1357 ret = __process_enable_global_app_for_uid(item);
1359 case PKGMGR_REQUEST_TYPE_DISABLE_GLOBAL_APP_FOR_UID:
1360 ret = __process_disable_global_app_for_uid(item);
1362 case PKGMGR_REQUEST_TYPE_KILL:
1363 ret = __process_kill(item);
1365 case PKGMGR_REQUEST_TYPE_CHECK:
1366 ret = __process_check(item);
1368 case PKGMGR_REQUEST_TYPE_GENERATE_LICENSE_REQUEST:
1369 ret = __process_generate_license_request(item);
1371 case PKGMGR_REQUEST_TYPE_REGISTER_LICENSE:
1372 ret = __process_register_license(item);
1374 case PKGMGR_REQUEST_TYPE_DECRYPT_PACKAGE:
1375 ret = __process_decrypt_package(item);
1377 case PKGMGR_REQUEST_TYPE_ENABLE_APP_SPLASH_SCREEN:
1378 ret = __process_update_app_splash_screen(item, 1);
1380 case PKGMGR_REQUEST_TYPE_DISABLE_APP_SPLASH_SCREEN:
1381 ret = __process_update_app_splash_screen(item, 0);
1383 case PKGMGR_REQUEST_TYPE_SET_RESTRICTION_MODE:
1384 ret = __process_set_restriction_mode(item);
1386 case PKGMGR_REQUEST_TYPE_UNSET_RESTRICTION_MODE:
1387 ret = __process_unset_restriction_mode(item);
1389 case PKGMGR_REQUEST_TYPE_GET_RESTRICTION_MODE:
1390 ret = __process_get_restriction_mode(item);
1403 #define IS_WHITESPACE(CHAR) \
1404 ((CHAR == ' ' || CHAR == '\t' || CHAR == '\r' || CHAR == '\n') ? TRUE : FALSE)
1406 void _app_str_trim(char *input)
1408 char *trim_str = input;
1413 while (*input != 0) {
1414 if (!IS_WHITESPACE(*input)) {
1425 char *_get_backend_cmd(char *type)
1428 char buffer[1024] = { 0 };
1429 char *command = NULL;
1431 fp = fopen(PKG_CONF_PATH, "r");
1437 while (fgets(buffer, 1024, fp) != NULL) {
1438 if (buffer[0] == '#')
1441 _app_str_trim(buffer);
1443 if ((path = strstr(buffer, PKG_BACKEND)) != NULL) {
1444 DBG("buffer [%s]", buffer);
1445 path = path + strlen(PKG_BACKEND);
1446 DBG("path [%s]", path);
1449 (char *)malloc(sizeof(char) * strlen(path) +
1451 if (command == NULL) {
1456 size = strlen(path) + strlen(type) + 1;
1457 snprintf(command, size, "%s%s", path, type);
1458 command[strlen(path) + strlen(type)] = '\0';
1459 DBG("command [%s]", command);
1467 memset(buffer, 0x00, 1024);
1473 return NULL; /* cannot find proper command */
1476 int main(int argc, char *argv[])
1480 DBG("server start");
1482 r = _pm_queue_init();
1484 DBG("Queue Initialization Failed\n");
1488 r = __init_backend_info();
1490 DBG("backend info init failed");
1494 r = __init_request_handler();
1496 ERR("dbus init failed");
1500 if (__register_signal_handler()) {
1501 ERR("failed to register signal handler");
1505 #if !GLIB_CHECK_VERSION(2,35,0)
1508 mainloop = g_main_loop_new(NULL, FALSE);
1510 ERR("g_main_loop_new failed");
1514 DBG("Main loop is created.");
1516 g_main_loop_run(mainloop);
1518 DBG("Quit main loop.");
1519 __fini_request_handler();
1520 __fini_backend_info();
1523 DBG("package manager server terminated.");