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>
32 #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>
45 #ifdef TIZEN_FEATURE_CSR
46 #include <csr-content-screening.h>
49 #include "pkgmgr_installer.h"
50 #include "pkgmgr-server.h"
52 #include "package-manager.h"
55 #define NO_MATCHING_FILE 11
58 #define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
62 #define EXT_STORAGE_GROUP 10001
63 #define EXT_STORAGE_APPDATA_GROUP 10002
64 #define MEDIA_STORAGE_GROUP 10502
65 #define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
79 8 bit value to represent maximum 8 backends.
80 Each bit position corresponds to a queue slot which
81 is dynamically determined.
83 char backend_busy = 0;
84 extern int num_of_backends;
86 struct signal_info_t {
91 static int pipe_sig[2];
92 static GIOChannel *pipe_io;
93 static guint pipe_wid;
96 extern queue_info_map *start;
99 GMainLoop *mainloop = NULL;
104 OPERATION_INSTALL = 0,
111 static int __check_backend_status_for_exit(void);
112 static int __check_queue_status_for_exit(void);
113 static int __is_backend_busy(int position);
114 static void __set_backend_busy(int position);
115 static void __set_backend_free(int position);
116 static void sighandler(int signo);
118 gboolean exit_server(void *data);
120 /* To check whether a particular backend is free/busy*/
121 static int __is_backend_busy(int position)
123 return backend_busy & 1<<position;
125 /*To set a particular backend as busy*/
126 static void __set_backend_busy(int position)
128 backend_busy = backend_busy | 1<<position;
130 /*To set a particular backend as free */
131 static void __set_backend_free(int position)
133 backend_busy = backend_busy & ~(1<<position);
136 static gboolean pipe_io_handler(GIOChannel *io, GIOCondition cond, gpointer data)
142 struct signal_info_t info;
143 backend_info *ptr = begin;
145 s = g_io_channel_read_chars(io, (gchar *)&info, sizeof(struct signal_info_t), &len, &err);
146 if (s != G_IO_STATUS_NORMAL) {
147 ERR("Signal pipe read failed: %s", err->message);
152 for (x = 0; x < num_of_backends; x++, ptr++) {
153 if (ptr && ptr->pid == info.pid)
157 if (x == num_of_backends) {
158 ERR("Unknown child exit");
162 __set_backend_free(x);
163 if (WIFSIGNALED(info.status)) {
164 __send_fail_signal(ptr);
165 DBG("backend[%s] exit with signal[%d]", ptr->pkgtype,
166 WTERMSIG(info.status));
167 } else if (WEXITSTATUS(info.status)) {
168 DBG("backend[%s] exit with error", ptr->pkgtype);
170 DBG("backend[%s] exit", ptr->pkgtype);
173 g_idle_add(queue_job, NULL);
178 static int __init_backend_info(void)
182 /*Allocate memory for holding pid, pkgtype and pkgid*/
183 ptr = (backend_info*)calloc(num_of_backends, sizeof(backend_info));
185 DBG("Malloc Failed\n");
190 if (pipe(pipe_sig)) {
191 ERR("create pipe failed");
195 pipe_io = g_io_channel_unix_new(pipe_sig[0]);
196 g_io_channel_set_encoding(pipe_io, NULL, NULL);
197 g_io_channel_set_buffered(pipe_io, FALSE);
198 pipe_wid = g_io_add_watch(pipe_io, G_IO_IN, pipe_io_handler, NULL);
203 static void __fini_backend_info(void)
205 g_source_remove(pipe_wid);
206 g_io_channel_unref(pipe_io);
210 /*Free backend info */
214 static void sighandler(int signo)
216 struct signal_info_t info;
217 char buf[1024] = {0, };
219 info.pid = waitpid(-1, &info.status, WNOHANG);
220 if (write(pipe_sig[1], &info, sizeof(struct signal_info_t)) < 0)
221 ERR("failed to write result: %s", strerror_r(errno, buf, sizeof(buf)));
224 static int __register_signal_handler(void)
226 static int sig_reg = 0;
227 struct sigaction act;
232 act.sa_handler = sighandler;
233 sigemptyset(&act.sa_mask);
234 act.sa_flags = SA_NOCLDSTOP;
235 if (sigaction(SIGCHLD, &act, NULL) < 0) {
236 ERR("signal: SIGCHLD failed\n");
240 g_timeout_add_seconds(2, exit_server, NULL);
246 static int __check_backend_status_for_exit(void)
249 for (i = 0; i < num_of_backends; i++) {
250 if (__is_backend_busy(i))
256 static int __check_queue_status_for_exit(void)
258 pm_queue_data *head[MAX_QUEUE_NUM] = {NULL,};
259 queue_info_map *ptr = NULL;
264 for (i = 0; i < entries; i++) {
265 if (ptr->queue_slot <= slot) {
269 slot = ptr->queue_slot;
274 for (i = 0; i < num_of_backends; i++) {
281 gboolean exit_server(void *data)
283 DBG("exit_server Start\n");
284 if (__check_backend_status_for_exit() &&
285 __check_queue_status_for_exit()) {
286 if (!getenv("PMS_STANDALONE")) {
287 g_main_loop_quit(mainloop);
294 #ifdef TIZEN_FEATURE_CSR
295 static int __check_csr(backend_info *ptr)
297 csr_cs_context_h context = NULL;
298 csr_cs_malware_h detected = NULL;
301 ret = csr_cs_context_create(&context);
302 if (ret != CSR_ERROR_NONE) {
303 ERR("Failed to create csr context");
308 ret = csr_cs_scan_file(context, ptr->pkgid, &detected);
309 DBG("CSR result[%d]", ret);
311 csr_cs_context_destroy(context);
312 if (detected != NULL) {
313 ERR("CSR Denied[%s] Installation", ptr->pkgid);
322 static void __make_pid_info_file(char *req_key, int pid, uid_t uid)
327 char buf[MAX_PKG_TYPE_LEN] = {0};
328 char info_file[PATH_MAX] = {'\0'};
330 struct passwd *pwd_result;
335 ret = getpwuid_r(uid, &pwd, buf, sizeof(buf), &pwd_result);
336 if (ret != 0 || pwd_result == NULL) {
337 ERR("get uid failed(%d) for user(%d)", ret, uid);
340 DBG("uid(%d), gid(%d)", uid, pwd.pw_gid);
342 snprintf(info_file, PATH_MAX, "/tmp/pkgmgr/%s", req_key);
344 DBG("info_path(%s)", info_file);
345 file = fopen(info_file, "w");
347 ERR("Couldn't open the file(%s)", info_file);
351 snprintf(buf, MAX_PKG_TYPE_LEN, "%d\n", pid);
352 fwrite(buf, 1, strlen(buf), file);
356 if (fchmod(fd, 0777) < 0)
357 ERR("chmod failed, errno(%d)", errno);
358 if (fchown(fd, uid, pwd.pw_gid) < 0)
359 ERR("chown failed, errno(%d)", errno);
364 static int __kill_app(char *appid, uid_t uid)
370 is_running = aul_app_is_running_for_uid(appid, uid);
371 /* app is not running */
375 pid = aul_app_get_pid_for_uid(appid, uid);
379 ret = aul_terminate_pid_for_uid(pid, uid);
380 if (ret != AUL_R_OK) {
381 ERR("failed to terminate app(%d)", appid);
388 static int __check_app(char *appid, uid_t uid)
393 is_running = aul_app_is_running_for_uid(appid, uid);
397 pid = aul_app_get_pid_for_uid(appid, uid);
402 static int __pkgcmd_app_cb(const pkgmgrinfo_appinfo_h handle, void *user_data)
409 pkgcmd_data *pdata = (pkgcmd_data *)user_data;
411 if (handle == NULL) {
412 perror("appinfo handle is NULL\n");
415 ret = pkgmgrinfo_appinfo_get_exec(handle, &exec);
417 perror("Failed to get app exec path\n");
420 ret = pkgmgrinfo_appinfo_get_appid(handle, &appid);
422 perror("Failed to get appid\n");
425 ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid);
427 perror("Failed to get pkgid\n");
431 if (strcmp(pdata->cmd, "kill") == 0) {
432 pid = __check_app(appid, pdata->uid);
434 ret = __kill_app(appid, pdata->uid);
435 } else if (strcmp(pdata->cmd, "check") == 0) {
436 pid = __check_app(appid, pdata->uid);
439 __make_pid_info_file(pkgid, pid, pdata->uid);
444 void free_user_context(user_ctx* ctx)
451 /* env variable ends by NULL element */
461 int set_environement(user_ctx *ctx)
472 if (ctx->uid != APPFW_UID) {
473 if (setuid(ctx->uid)) {
474 ERR("setuid failed: %d", errno);
478 if (setgid(ctx->gid)) {
479 ERR("setgid failed: %d", errno);
484 n = getgroups(0, NULL);
486 ERR("Failed to get the number of supplementary group IDs");
490 groups = (gid_t *)calloc(1, sizeof(gid_t) * (n + 3));
491 if (groups == NULL) {
492 ERR("out of memory");
496 n = getgroups(n, groups);
498 ERR("Failed to get list of supplementary group IDs");
503 groups[n++] = EXT_STORAGE_GROUP;
504 groups[n++] = EXT_STORAGE_APPDATA_GROUP;
505 groups[n++] = MEDIA_STORAGE_GROUP;
507 if (setgroups(n, groups) < 0) {
508 ERR("setgroups failed: %d", errno);
515 /* env variable ends by NULL element */
517 if (putenv(env[i]) != 0)
524 user_ctx *get_user_context(uid_t uid)
526 /* we can use getpwnam because this is used only after a
527 * fork and just before an execv
528 * No concurrencial call can corrupt the data
529 * returned by getpwuid
531 user_ctx *context_res;
533 char buf[1024] = {0, };
534 struct passwd pwd, *result;
539 ret = getpwuid_r(uid, &pwd, buf, sizeof(buf), &result);
540 if (ret != 0 || result == NULL)
544 context_res = (user_ctx *)malloc(sizeof(user_ctx));
549 env = (char **)malloc(3 * sizeof(char *));
554 /* Build environment context */
555 len = snprintf(NULL, 0, "HOME=%s", pwd.pw_dir);
556 env[0] = (char *)malloc((len + 1) * sizeof(char));
557 if (env[0] == NULL) {
561 snprintf(env[0], len + 1, "HOME=%s", pwd.pw_dir);
562 len = snprintf(NULL, 0, "USER=%s", pwd.pw_name);
563 env[1] = (char *)malloc((len + 1) * sizeof(char));
564 if (env[1] == NULL) {
568 snprintf(env[1], len + 1, "USER=%s", pwd.pw_name);
576 /* env variable ends by NULL element */
577 while (env && env[i]) {
584 context_res->env = env;
585 context_res->uid = uid;
586 context_res->gid = pwd.pw_gid;
591 static char **__generate_argv(const char *args)
593 /* Create args vector
594 * req_id + pkgid + args
596 * vector size = # of args +
597 *(req_id + pkgid + NULL termination = 3)
598 * Last value must be NULL for execv.
606 ret_parse = g_shell_parse_argv(args, &argcp, &argvp, &gerr);
607 if (FALSE == ret_parse) {
608 DBG("Failed to split args: %s", args);
609 DBG("messsage: %s", gerr->message);
614 for (i = 0; i < argcp; i++)
615 DBG(">>>>>> argsv[%d]=%s", i, argvp[i]);
620 void __set_environment(gpointer user_data)
622 user_ctx *ctx = (user_ctx *)user_data;
624 if (set_environement(ctx))
625 DBG("Failed to set env for the user : %d", ctx->uid);
628 static int __fork_and_exec_with_args(char **argv, uid_t uid)
630 user_ctx* user_context;
631 GError *error = NULL;
635 user_context = get_user_context(uid);
637 DBG("Failed to getenv");
641 ret = g_spawn_async(NULL, argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD,
642 __set_environment, (gpointer)user_context, &pid,
645 ERR("Failed to excute backend: %s", error->message);
649 free_user_context(user_context);
654 static int __change_item_info(pm_dbus_msg *item, uid_t uid, bool *is_global)
658 pkgmgrinfo_appinfo_h handle = NULL;
660 switch (item->req_type) {
661 case PKGMGR_REQUEST_TYPE_DISABLE_APP:
662 case PKGMGR_REQUEST_TYPE_DISABLE_GLOBAL_APP_FOR_UID:
663 case PKGMGR_REQUEST_TYPE_ENABLE_APP_SPLASH_SCREEN:
664 case PKGMGR_REQUEST_TYPE_DISABLE_APP_SPLASH_SCREEN:
665 ret = pkgmgrinfo_appinfo_get_usr_appinfo(item->pkgid, uid, &handle);
667 case PKGMGR_REQUEST_TYPE_ENABLE_APP:
668 case PKGMGR_REQUEST_TYPE_ENABLE_GLOBAL_APP_FOR_UID:
669 ret = pkgmgrinfo_appinfo_get_usr_disabled_appinfo(item->pkgid, uid, &handle);
672 return PMINFO_R_ERROR;
675 if (ret != PMINFO_R_OK)
676 return PMINFO_R_ERROR;
678 ret = pkgmgrinfo_appinfo_is_global(handle, is_global);
679 if (ret != PMINFO_R_OK)
682 if ((item->req_type == PKGMGR_REQUEST_TYPE_DISABLE_APP
683 || item->req_type == PKGMGR_REQUEST_TYPE_ENABLE_APP)
685 ret = PMINFO_R_ERROR;
687 } else if ((item->req_type == PKGMGR_REQUEST_TYPE_DISABLE_GLOBAL_APP_FOR_UID
688 || item->req_type == PKGMGR_REQUEST_TYPE_ENABLE_GLOBAL_APP_FOR_UID)
690 ret = PMINFO_R_ERROR;
694 ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid);
695 if (ret != PMINFO_R_OK)
698 strncpy(item->appid, item->pkgid, sizeof(item->pkgid) - 1);
699 memset((item->pkgid), 0, MAX_PKG_NAME_LEN);
700 strncpy(item->pkgid, pkgid, sizeof(item->pkgid) - 1);
703 pkgmgrinfo_appinfo_destroy_appinfo(handle);
708 static int __process_install(pm_dbus_msg *item)
712 char args[MAX_PKG_ARGS_LEN] = {'\0', };
715 backend_cmd = _get_backend_cmd(item->pkg_type);
716 if (backend_cmd == NULL)
719 snprintf(args, sizeof(args), "%s -k %s -i %s -u %d %s", backend_cmd,
720 item->req_id, item->pkgid, (int)item->uid, item->args);
722 argv = __generate_argv(args);
724 pid = __fork_and_exec_with_args(argv, APPFW_UID);
731 static int __process_mount_install(pm_dbus_msg *item)
735 char args[MAX_PKG_ARGS_LEN] = {'\0', };
738 backend_cmd = _get_backend_cmd(item->pkg_type);
739 if (backend_cmd == NULL)
742 snprintf(args, sizeof(args), "%s -k %s -w %s -u %d %s", backend_cmd,
743 item->req_id, item->pkgid, (int)item->uid, item->args);
745 argv = __generate_argv(args);
747 pid = __fork_and_exec_with_args(argv, APPFW_UID);
754 static int __process_reinstall(pm_dbus_msg *item)
758 char args[MAX_PKG_ARGS_LEN];
761 backend_cmd = _get_backend_cmd(item->pkg_type);
762 if (backend_cmd == NULL)
765 snprintf(args, sizeof(args), "%s -k %s -r %s -u %d", backend_cmd,
766 item->req_id, item->pkgid, (int)item->uid);
767 argv = __generate_argv(args);
769 pid = __fork_and_exec_with_args(argv, APPFW_UID);
777 static int __process_uninstall(pm_dbus_msg *item)
781 char args[MAX_PKG_ARGS_LEN];
784 backend_cmd = _get_backend_cmd(item->pkg_type);
785 if (backend_cmd == NULL)
788 snprintf(args, sizeof(args), "%s -k %s -d %s -u %d", backend_cmd,
789 item->req_id, item->pkgid, (int)item->uid);
790 argv = __generate_argv(args);
792 pid = __fork_and_exec_with_args(argv, APPFW_UID);
800 static int __process_move(pm_dbus_msg *item)
804 char args[MAX_PKG_ARGS_LEN];
807 backend_cmd = _get_backend_cmd(item->pkg_type);
808 if (backend_cmd == NULL)
811 snprintf(args, sizeof(args), "%s -k %s -m %s -u %d -t %s", backend_cmd,
812 item->req_id, item->pkgid, (int)item->uid, item->args);
813 argv = __generate_argv(args);
815 pid = __fork_and_exec_with_args(argv, APPFW_UID);
823 static int __process_enable_pkg(pm_dbus_msg *item)
827 char args[MAX_PKG_ARGS_LEN];
830 backend_cmd = _get_backend_cmd(item->pkg_type);
831 if (backend_cmd == NULL)
834 snprintf(args, sizeof(args), "%s -k %s -u %d -A %s", backend_cmd,
835 item->req_id, (int)item->uid, item->pkgid);
836 argv = __generate_argv(args);
838 pid = __fork_and_exec_with_args(argv, APPFW_UID);
846 static int __process_disable_pkg(pm_dbus_msg *item)
850 char args[MAX_PKG_ARGS_LEN];
853 backend_cmd = _get_backend_cmd(item->pkg_type);
854 if (backend_cmd == NULL)
857 snprintf(args, sizeof(args), "%s -k %s -u %d -D %s", backend_cmd,
858 item->req_id, (int)item->uid, item->pkgid);
859 argv = __generate_argv(args);
861 pid = __fork_and_exec_with_args(argv, APPFW_UID);
869 static int __process_enable_app(pm_dbus_msg *item)
872 bool is_global = false;
874 /* get actual pkgid and replace it to appid which is currently stored at pkgid variable */
875 ret = __change_item_info(item, item->uid, &is_global);
876 if (ret != PMINFO_R_OK || strlen(item->appid) == 0) {
877 __send_app_signal(item->uid, item->req_id, item->pkgid, item->pkgid,
878 PKGMGR_INSTALLER_START_KEY_STR,
879 PKGMGR_INSTALLER_APP_ENABLE_EVENT_STR, item->req_type);
880 __send_app_signal(item->uid, item->req_id, item->pkgid, item->pkgid,
881 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_FAIL_EVENT_STR,
886 __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
887 PKGMGR_INSTALLER_START_KEY_STR,
888 PKGMGR_INSTALLER_APP_ENABLE_EVENT_STR, item->req_type);
890 ret = pkgmgr_parser_update_app_disable_info_in_usr_db(item->appid, item->uid, 0);
891 if (ret != PMINFO_R_OK)
892 __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
893 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_FAIL_EVENT_STR,
896 __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
897 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_OK_EVENT_STR,
904 static int __process_disable_app(pm_dbus_msg *item)
907 bool is_global = false;
909 /* get actual pkgid and replace it to appid which is currently stored at pkgid variable */
910 ret = __change_item_info(item, item->uid, &is_global);
911 if (ret != PMINFO_R_OK || strlen(item->appid) == 0) {
912 __send_app_signal(item->uid, item->req_id, item->pkgid, item->pkgid,
913 PKGMGR_INSTALLER_START_KEY_STR,
914 PKGMGR_INSTALLER_APP_DISABLE_EVENT_STR, item->req_type);
915 __send_app_signal(item->uid, item->req_id, item->pkgid, item->pkgid,
916 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_FAIL_EVENT_STR,
921 __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
922 PKGMGR_INSTALLER_START_KEY_STR,
923 PKGMGR_INSTALLER_APP_DISABLE_EVENT_STR, item->req_type);
925 ret = __kill_app(item->appid, item->uid);
927 __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
928 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_FAIL_EVENT_STR,
932 ret = pkgmgr_parser_update_app_disable_info_in_usr_db(item->appid, item->uid, 1);
933 if (ret != PMINFO_R_OK)
934 __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
935 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_FAIL_EVENT_STR,
938 __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
939 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_OK_EVENT_STR,
945 static int __process_enable_global_app_for_uid(pm_dbus_msg *item)
948 bool is_global = true;
950 /* get actual pkgid and replace it to appid which is currently stored at pkgid variable */
951 ret = __change_item_info(item, item->uid, &is_global);
952 if (ret != PMINFO_R_OK || strlen(item->appid) == 0) {
953 __send_app_signal(item->uid, item->req_id, item->pkgid, item->pkgid,
954 PKGMGR_INSTALLER_START_KEY_STR,
955 PKGMGR_INSTALLER_GLOBAL_APP_ENABLE_FOR_UID, item->req_type);
956 __send_app_signal(item->uid, item->req_id, item->pkgid, item->pkgid,
957 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_FAIL_EVENT_STR,
962 __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
963 PKGMGR_INSTALLER_START_KEY_STR,
964 PKGMGR_INSTALLER_GLOBAL_APP_ENABLE_FOR_UID, item->req_type);
966 ret = pkgmgr_parser_update_global_app_disable_for_uid_info_in_db(item->appid, item->uid, 0);
967 if (ret != PMINFO_R_OK)
968 __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
969 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_FAIL_EVENT_STR,
972 __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
973 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_OK_EVENT_STR,
979 static int __process_disable_global_app_for_uid(pm_dbus_msg *item)
982 bool is_global = true;
984 /* get actual pkgid and replace it to appid which is currently stored at pkgid variable */
985 ret = __change_item_info(item, GLOBAL_USER, &is_global);
986 if (ret != PMINFO_R_OK || strlen(item->appid) == 0) {
987 __send_app_signal(item->uid, item->req_id,
988 item->pkgid, item->pkgid,
989 PKGMGR_INSTALLER_START_KEY_STR,
990 PKGMGR_INSTALLER_GLOBAL_APP_DISABLE_FOR_UID, item->req_type);
991 __send_app_signal(item->uid, item->req_id, item->pkgid, item->pkgid,
992 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_FAIL_EVENT_STR,
997 __send_app_signal(item->uid, item->req_id,
998 item->pkgid, item->appid,
999 PKGMGR_INSTALLER_START_KEY_STR,
1000 PKGMGR_INSTALLER_GLOBAL_APP_DISABLE_FOR_UID, item->req_type);
1002 ret = __kill_app(item->appid, item->uid);
1003 ret = pkgmgr_parser_update_global_app_disable_for_uid_info_in_db(item->appid,
1006 if (ret != PMINFO_R_OK)
1007 __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
1008 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_FAIL_EVENT_STR,
1011 __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
1012 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_OK_EVENT_STR,
1018 static int __process_getsize(pm_dbus_msg *item)
1020 static const char *backend_cmd = "/usr/bin/pkg_getsize";
1022 char args[MAX_PKG_ARGS_LEN];
1025 snprintf(args, sizeof(args), "%s %s %s -k %s", backend_cmd, item->pkgid,
1026 item->args, item->req_id);
1027 argv = __generate_argv(args);
1028 pid = __fork_and_exec_with_args(argv, item->uid);
1035 static int __process_cleardata(pm_dbus_msg *item)
1039 char args[MAX_PKG_ARGS_LEN];
1042 backend_cmd = _get_backend_cmd(item->pkg_type);
1043 if (backend_cmd == NULL)
1046 /* TODO: set movetype */
1047 snprintf(args, sizeof(args), "%s -k %s -c %s -u %d", backend_cmd,
1048 item->req_id, item->pkgid, (int)item->uid);
1049 argv = __generate_argv(args);
1051 pid = __fork_and_exec_with_args(argv, APPFW_UID);
1059 static int __process_clearcache(pm_dbus_msg *item)
1061 static const char *backend_cmd = "/usr/bin/pkg_clearcache";
1063 char args[MAX_PKG_ARGS_LEN];
1066 snprintf(args, sizeof(args), "%s %s", backend_cmd, item->pkgid);
1067 argv = __generate_argv(args);
1068 pid = __fork_and_exec_with_args(argv, item->uid);
1075 static int __process_kill(pm_dbus_msg *item)
1078 pkgmgrinfo_pkginfo_h handle;
1079 pkgcmd_data *pdata = NULL;
1081 ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(item->pkgid, item->uid,
1084 ERR("Failed to get handle");
1088 pdata = calloc(1, sizeof(pkgcmd_data));
1089 if (pdata == NULL) {
1090 ERR("memory alloc failed");
1093 pdata->cmd = strdup("kill");
1094 if (pdata->cmd == NULL) {
1095 ERR("out of memory");
1100 pdata->uid = item->uid;
1101 ret = pkgmgrinfo_appinfo_get_usr_list(handle, PMINFO_ALL_APP,
1102 __pkgcmd_app_cb, pdata, item->uid);
1106 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1108 ERR("pkgmgrinfo_appinfo_get_list() failed");
1115 static int __process_check(pm_dbus_msg *item)
1118 pkgmgrinfo_pkginfo_h handle;
1119 pkgcmd_data *pdata = NULL;
1121 ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(item->pkgid, item->uid,
1124 ERR("Failed to get handle");
1128 pdata = calloc(1, sizeof(pkgcmd_data));
1129 if (pdata == NULL) {
1130 ERR("memory alloc failed");
1133 pdata->cmd = strdup("check");
1134 if (pdata->cmd == NULL) {
1135 ERR("out of memory");
1140 pdata->uid = item->uid;
1141 ret = pkgmgrinfo_appinfo_get_usr_list(handle, PMINFO_ALL_APP,
1142 __pkgcmd_app_cb, pdata, item->uid);
1146 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1148 ERR("pkgmgrinfo_appinfo_get_list() failed");
1155 static int __process_generate_license_request(pm_dbus_msg *item)
1159 char req_data[MAX_PKG_ARGS_LEN];
1160 unsigned int req_data_len;
1161 char license_url[MAX_PKG_ARGS_LEN];
1162 unsigned int license_url_len;
1164 resp_data = item->args;
1165 req_data_len = sizeof(req_data);
1166 license_url_len = sizeof(license_url);
1168 ret = drm_tizen_generate_license_request(resp_data, strlen(resp_data),
1169 req_data, &req_data_len, license_url, &license_url_len);
1170 if (ret != TADC_SUCCESS) {
1171 ERR("drm_tizen_generate_license_request failed: %d", ret);
1172 __return_value_to_caller(item->req_id, g_variant_new("(iss)",
1173 PKGMGR_R_ESYSTEM, "", ""));
1177 __return_value_to_caller(item->req_id,
1178 g_variant_new("(iss)", PKGMGR_R_OK, req_data,
1184 static int __process_register_license(pm_dbus_msg *item)
1189 resp_data = item->args;
1191 ret = drm_tizen_register_license(resp_data, strlen(resp_data));
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_decrypt_package(pm_dbus_msg *item)
1208 char *drm_file_path;
1209 char *decrypted_file_path;
1211 drm_file_path = item->pkgid;
1212 decrypted_file_path = item->args;
1214 /* TODO: check ownership of decrypted file */
1215 ret = drm_tizen_decrypt_package(drm_file_path, strlen(drm_file_path),
1216 decrypted_file_path, strlen(decrypted_file_path));
1217 if (ret != TADC_SUCCESS) {
1218 ERR("drm_tizen_register_license failed: %d", ret);
1219 __return_value_to_caller(item->req_id,
1220 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1224 __return_value_to_caller(item->req_id,
1225 g_variant_new("(i)", PKGMGR_R_OK));
1230 static int __process_update_app_splash_screen(pm_dbus_msg *item, int flag)
1233 bool is_global = false;
1236 ret = __change_item_info(item, item->uid, &is_global);
1237 if (ret != PMINFO_R_OK || strlen(item->appid) == 0)
1240 val = flag ? PKGMGR_INSTALLER_APP_ENABLE_SPLASH_SCREEN_EVENT_STR :
1241 PKGMGR_INSTALLER_APP_DISABLE_SPLASH_SCREEN_EVENT_STR;
1242 __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
1243 PKGMGR_INSTALLER_START_KEY_STR, val, item->req_type);
1246 ret = pkgmgr_parser_update_global_app_splash_screen_display_info_in_usr_db(
1247 item->appid, item->uid, flag);
1249 ret = pkgmgr_parser_update_app_splash_screen_display_info_in_usr_db(
1250 item->appid, item->uid, flag);
1251 if (ret != PMINFO_R_OK)
1252 __send_app_signal(item->uid, item->req_id, item->pkgid,
1253 item->appid, PKGMGR_INSTALLER_END_KEY_STR,
1254 PKGMGR_INSTALLER_FAIL_EVENT_STR,
1257 __send_app_signal(item->uid, item->req_id, item->pkgid,
1258 item->appid, PKGMGR_INSTALLER_END_KEY_STR,
1259 PKGMGR_INSTALLER_OK_EVENT_STR,
1265 static int __process_set_restriction_mode(pm_dbus_msg *item)
1270 mode = atoi(item->args);
1271 ret = _restriction_mode_set(item->uid, item->pkgid, mode);
1273 __return_value_to_caller(item->req_id,
1274 g_variant_new("(i)", ret));
1279 static int __process_unset_restriction_mode(pm_dbus_msg *item)
1284 mode = atoi(item->args);
1285 ret = _restriction_mode_unset(item->uid, item->pkgid, mode);
1287 __return_value_to_caller(item->req_id,
1288 g_variant_new("(i)", ret));
1293 static int __process_get_restriction_mode(pm_dbus_msg *item)
1298 ret = _restriction_mode_get(item->uid, item->pkgid, &mode);
1300 __return_value_to_caller(item->req_id,
1301 g_variant_new("(ii)", mode, ret));
1306 gboolean queue_job(void *data)
1308 pm_dbus_msg *item = NULL;
1313 /* Pop a job from queue */
1314 for (x = 0, ptr = begin; x < num_of_backends; x++, ptr++) {
1315 if (__is_backend_busy(x))
1318 item = _pm_queue_pop(x);
1319 if (item && item->req_type != -1)
1324 /* all backend messages queue are empty or busy */
1325 if (x == num_of_backends)
1328 /*save pkg type and pkg name for future*/
1329 strncpy(ptr->req_id, item->req_id, MAX_REQ_ID_LEN - 1);
1330 strncpy(ptr->pkgtype, item->pkg_type, MAX_PKG_TYPE_LEN - 1);
1331 strncpy(ptr->pkgid, item->pkgid, MAX_PKG_NAME_LEN - 1);
1332 strncpy(ptr->args, item->args, MAX_PKG_ARGS_LEN - 1);
1333 memset((item->appid), 0, MAX_PKG_NAME_LEN);
1334 ptr->uid = item->uid;
1335 ptr->req_type = item->req_type;
1336 DBG("handle request type [%d]", item->req_type);
1338 #ifdef TIZEN_FEATURE_CSR
1339 if (item->req_type == PKGMGR_REQUEST_TYPE_INSTALL ||
1340 item->req_type == PKGMGR_REQUEST_TYPE_MOUNT_INSTALL ||
1341 item->req_type == PKGMGR_REQUEST_TYPE_REINSTALL) {
1342 ret = __check_csr(ptr);
1345 __send_fail_signal(ptr);
1351 switch (item->req_type) {
1352 case PKGMGR_REQUEST_TYPE_INSTALL:
1353 __set_backend_busy(x);
1354 ret = __process_install(item);
1356 case PKGMGR_REQUEST_TYPE_MOUNT_INSTALL:
1357 __set_backend_busy(x);
1358 ret = __process_mount_install(item);
1360 case PKGMGR_REQUEST_TYPE_REINSTALL:
1361 __set_backend_busy(x);
1362 ret = __process_reinstall(item);
1364 case PKGMGR_REQUEST_TYPE_UNINSTALL:
1365 __set_backend_busy(x);
1366 ret = __process_uninstall(item);
1368 case PKGMGR_REQUEST_TYPE_MOVE:
1369 __set_backend_busy(x);
1370 ret = __process_move(item);
1372 case PKGMGR_REQUEST_TYPE_ENABLE_PKG:
1373 __set_backend_busy(x);
1374 ret = __process_enable_pkg(item);
1376 case PKGMGR_REQUEST_TYPE_DISABLE_PKG:
1377 __set_backend_busy(x);
1378 ret = __process_disable_pkg(item);
1380 case PKGMGR_REQUEST_TYPE_ENABLE_APP:
1381 ret = __process_enable_app(item);
1383 case PKGMGR_REQUEST_TYPE_DISABLE_APP:
1384 ret = __process_disable_app(item);
1386 case PKGMGR_REQUEST_TYPE_GETSIZE:
1387 __set_backend_busy(x);
1388 ret = __process_getsize(item);
1390 case PKGMGR_REQUEST_TYPE_CLEARDATA:
1391 __set_backend_busy(x);
1392 ret = __process_cleardata(item);
1394 case PKGMGR_REQUEST_TYPE_CLEARCACHE:
1395 __set_backend_busy(x);
1396 ret = __process_clearcache(item);
1398 case PKGMGR_REQUEST_TYPE_ENABLE_GLOBAL_APP_FOR_UID:
1399 ret = __process_enable_global_app_for_uid(item);
1401 case PKGMGR_REQUEST_TYPE_DISABLE_GLOBAL_APP_FOR_UID:
1402 ret = __process_disable_global_app_for_uid(item);
1404 case PKGMGR_REQUEST_TYPE_KILL:
1405 ret = __process_kill(item);
1407 case PKGMGR_REQUEST_TYPE_CHECK:
1408 ret = __process_check(item);
1410 case PKGMGR_REQUEST_TYPE_GENERATE_LICENSE_REQUEST:
1411 ret = __process_generate_license_request(item);
1413 case PKGMGR_REQUEST_TYPE_REGISTER_LICENSE:
1414 ret = __process_register_license(item);
1416 case PKGMGR_REQUEST_TYPE_DECRYPT_PACKAGE:
1417 ret = __process_decrypt_package(item);
1419 case PKGMGR_REQUEST_TYPE_ENABLE_APP_SPLASH_SCREEN:
1420 ret = __process_update_app_splash_screen(item, 1);
1422 case PKGMGR_REQUEST_TYPE_DISABLE_APP_SPLASH_SCREEN:
1423 ret = __process_update_app_splash_screen(item, 0);
1425 case PKGMGR_REQUEST_TYPE_SET_RESTRICTION_MODE:
1426 ret = __process_set_restriction_mode(item);
1428 case PKGMGR_REQUEST_TYPE_UNSET_RESTRICTION_MODE:
1429 ret = __process_unset_restriction_mode(item);
1431 case PKGMGR_REQUEST_TYPE_GET_RESTRICTION_MODE:
1432 ret = __process_get_restriction_mode(item);
1439 #ifdef TIZEN_FEATURE_CSR
1448 #define IS_WHITESPACE(CHAR) \
1449 ((CHAR == ' ' || CHAR == '\t' || CHAR == '\r' || CHAR == '\n') ? TRUE : FALSE)
1451 void _app_str_trim(char *input)
1453 char *trim_str = input;
1458 while (*input != 0) {
1459 if (!IS_WHITESPACE(*input)) {
1470 char *_get_backend_cmd(char *type)
1473 char buffer[1024] = { 0 };
1474 char *command = NULL;
1477 fp = fopen(PKG_CONF_PATH, "r");
1482 while (fgets(buffer, 1024, fp) != NULL) {
1483 if (buffer[0] == '#')
1486 _app_str_trim(buffer);
1488 if ((path = strstr(buffer, PKG_BACKEND)) != NULL) {
1489 DBG("buffer [%s]", buffer);
1490 path = path + strlen(PKG_BACKEND);
1491 DBG("path [%s]", path);
1494 (char *)malloc(sizeof(char) * strlen(path) +
1496 if (command == NULL) {
1501 size = strlen(path) + strlen(type) + 1;
1502 snprintf(command, size, "%s%s", path, type);
1503 command[strlen(path) + strlen(type)] = '\0';
1504 DBG("command [%s]", command);
1512 memset(buffer, 0x00, 1024);
1518 return NULL; /* cannot find proper command */
1521 int main(int argc, char *argv[])
1525 DBG("server start");
1527 r = _pm_queue_init();
1529 DBG("Queue Initialization Failed\n");
1533 r = __init_backend_info();
1535 DBG("backend info init failed");
1539 r = __init_request_handler();
1541 ERR("dbus init failed");
1545 if (__register_signal_handler()) {
1546 ERR("failed to register signal handler");
1550 #if !GLIB_CHECK_VERSION(2, 35, 0)
1553 mainloop = g_main_loop_new(NULL, FALSE);
1555 ERR("g_main_loop_new failed");
1559 DBG("Main loop is created.");
1561 g_main_loop_run(mainloop);
1563 DBG("Quit main loop.");
1564 __fini_request_handler();
1565 __fini_backend_info();
1568 DBG("package manager server terminated.");