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>
40 #include <pkgmgr-info.h>
41 #include <pkgmgr/pkgmgr_parser.h>
42 #include <tzplatform_config.h>
43 #include <drm-tizen-apps.h>
45 #include "pkgmgr_installer.h"
46 #include "pkgmgr-server.h"
48 #include "comm_config.h"
49 #include "package-manager.h"
52 #define NO_MATCHING_FILE 11
55 #define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
65 8 bit value to represent maximum 8 backends.
66 Each bit position corresponds to a queue slot which
67 is dynamically determined.
69 char backend_busy = 0;
70 extern int num_of_backends;
72 struct signal_info_t {
77 static int pipe_sig[2];
78 static GIOChannel *pipe_io;
79 static guint pipe_wid;
82 extern queue_info_map *start;
85 GMainLoop *mainloop = NULL;
90 OPERATION_INSTALL = 0,
97 static int __check_backend_status_for_exit(void);
98 static int __check_queue_status_for_exit(void);
99 static int __is_backend_busy(int position);
100 static void __set_backend_busy(int position);
101 static void __set_backend_free(int position);
102 static void sighandler(int signo);
104 gboolean exit_server(void *data);
106 /* To check whether a particular backend is free/busy*/
107 static int __is_backend_busy(int position)
109 return backend_busy & 1<<position;
111 /*To set a particular backend as busy*/
112 static void __set_backend_busy(int position)
114 backend_busy = backend_busy | 1<<position;
116 /*To set a particular backend as free */
117 static void __set_backend_free(int position)
119 backend_busy = backend_busy & ~(1<<position);
122 static int __is_global(uid_t uid)
124 return (uid == OWNER_ROOT || uid == GLOBAL_USER) ? 1 : 0;
127 static const char *__get_recovery_file_path(uid_t uid)
131 if (!__is_global(uid))
132 tzplatform_set_user(uid);
134 path = tzplatform_getenv(__is_global(uid)
135 ? TZ_SYS_RW_PACKAGES : TZ_USER_PACKAGES);
137 tzplatform_reset_user();
142 static void __set_recovery_mode(uid_t uid, char *pkgid, char *pkg_type)
144 char recovery_file[MAX_PKG_NAME_LEN] = { 0, };
145 char buffer[MAX_PKG_NAME_LEN] = { 0 };
146 char *pkgid_tmp = NULL;
147 FILE *rev_file = NULL;
150 DBG("pkgid is null\n");
154 /*if pkgid has a "/"charactor, that is a path name for installation, then extract pkgid from absolute path*/
155 if (strstr(pkgid, "/")) {
156 pkgid_tmp = strrchr(pkgid, '/') + 1;
157 if (pkgid_tmp == NULL) {
158 DBG("pkgid_tmp[%s] is null\n", pkgid);
161 snprintf(recovery_file, sizeof(recovery_file), "%s/%s", __get_recovery_file_path(uid), pkgid_tmp);
163 snprintf(recovery_file, sizeof(recovery_file), "%s/%s", __get_recovery_file_path(uid), pkgid);
166 rev_file = fopen(recovery_file, "w");
167 if (rev_file== NULL) {
168 DBG("rev_file[%s] is null\n", recovery_file);
172 snprintf(buffer, MAX_PKG_NAME_LEN, "pkgid : %s\n", pkgid);
173 fwrite(buffer, sizeof(char), strlen(buffer), rev_file);
178 static void __unset_recovery_mode(uid_t uid, char *pkgid, char *pkg_type)
181 char recovery_file[MAX_PKG_NAME_LEN] = { 0, };
182 char *pkgid_tmp = NULL;
185 DBG("pkgid is null\n");
189 /*if pkgid has a "/"charactor, that is a path name for installation, then extract pkgid from absolute path*/
190 if (strstr(pkgid, "/")) {
191 pkgid_tmp = strrchr(pkgid, '/') + 1;
192 if (pkgid_tmp == NULL) {
193 DBG("pkgid_tmp[%s] is null\n", pkgid);
196 snprintf(recovery_file, sizeof(recovery_file), "%s/%s", __get_recovery_file_path(uid), pkgid_tmp);
198 snprintf(recovery_file, sizeof(recovery_file), "%s/%s", __get_recovery_file_path(uid), pkgid);
201 ret = remove(recovery_file);
203 DBG("remove recovery_file[%s] fail\n", recovery_file);
206 static void __send_app_signal(uid_t uid, const char *req_id,
207 const char *pkg_type, const char *pkgid, const char *appid,
208 const char *key, const char *val)
210 pkgmgr_installer *pi;
212 pi = pkgmgr_installer_new();
214 DBG("Failure in creating the pkgmgr_installer object");
218 if (pkgmgr_installer_set_request_type(pi,PKGMGR_REQ_ENABLE_DISABLE_APP))
220 if (pkgmgr_installer_set_session_id(pi, req_id))
222 pkgmgr_installer_send_app_signal(pi, pkg_type, pkgid, appid, key, val);
225 pkgmgr_installer_free(pi);
230 static void send_fail_signal(char *pname, char *ptype, char *args)
232 DBG("send_fail_signal start\n");
237 pkgmgr_installer *pi;
238 pi = pkgmgr_installer_new();
240 DBG("Failure in creating the pkgmgr_installer object");
243 ret_parse = g_shell_parse_argv(args,
244 &argcp, &argvp, &gerr);
245 if (FALSE == ret_parse) {
246 DBG("Failed to split args: %s", args);
247 DBG("messsage: %s", gerr->message);
248 pkgmgr_installer_free(pi);
252 pkgmgr_installer_receive_request(pi, argcp, argvp);
253 pkgmgr_installer_send_signal(pi, ptype, pname, "end", "fail");
254 pkgmgr_installer_free(pi);
258 static gboolean pipe_io_handler(GIOChannel *io, GIOCondition cond, gpointer data)
264 struct signal_info_t info;
265 backend_info *ptr = begin;
267 s = g_io_channel_read_chars(io, (gchar *)&info, sizeof(struct signal_info_t), &len, &err);
268 if (s != G_IO_STATUS_NORMAL) {
269 ERR("Signal pipe read failed: %s", err->message);
274 for (x = 0; x < num_of_backends; x++, ptr++) {
275 if (ptr && ptr->pid == info.pid)
279 if (x == num_of_backends) {
280 ERR("Unknown child exit");
284 __set_backend_free(x);
285 __unset_recovery_mode(ptr->uid, ptr->pkgid, ptr->pkgtype);
286 if (WIFSIGNALED(info.status) || WEXITSTATUS(info.status)) {
287 send_fail_signal(ptr->pkgid, ptr->pkgtype, ptr->args);
288 DBG("backend[%s] exit with error", ptr->pkgtype);
290 DBG("backend[%s] exit", ptr->pkgtype);
293 g_idle_add(queue_job, NULL);
298 static int __init_backend_info(void)
302 /*Allocate memory for holding pid, pkgtype and pkgid*/
303 ptr = (backend_info*)calloc(num_of_backends, sizeof(backend_info));
305 DBG("Malloc Failed\n");
310 if (pipe(pipe_sig)) {
311 ERR("create pipe failed");
315 pipe_io = g_io_channel_unix_new(pipe_sig[0]);
316 g_io_channel_set_encoding(pipe_io, NULL, NULL);
317 g_io_channel_set_buffered(pipe_io, FALSE);
318 pipe_wid = g_io_add_watch(pipe_io, G_IO_IN, pipe_io_handler, NULL);
323 static void __fini_backend_info(void)
325 g_source_remove(pipe_wid);
326 g_io_channel_unref(pipe_io);
330 /*Free backend info */
334 static void sighandler(int signo)
336 struct signal_info_t info;
338 info.pid = waitpid(-1, &info.status, WNOHANG);
339 if (write(pipe_sig[1], &info, sizeof(struct signal_info_t)) < 0)
340 ERR("failed to write result: %s", strerror(errno));
343 static int __register_signal_handler(void)
345 static int sig_reg = 0;
346 struct sigaction act;
351 act.sa_handler = sighandler;
352 sigemptyset(&act.sa_mask);
353 act.sa_flags = SA_NOCLDSTOP;
354 if (sigaction(SIGCHLD, &act, NULL) < 0) {
355 ERR("signal: SIGCHLD failed\n");
359 g_timeout_add_seconds(2, exit_server, NULL);
365 static int __check_backend_status_for_exit(void)
368 for(i = 0; i < num_of_backends; i++)
370 if (!__is_backend_busy(i))
378 static int __check_queue_status_for_exit(void)
380 pm_queue_data *head[MAX_QUEUE_NUM] = {NULL,};
381 queue_info_map *ptr = NULL;
386 for(i = 0; i < entries; i++)
388 if (ptr->queue_slot <= slot) {
394 slot = ptr->queue_slot;
399 for(i = 0; i < num_of_backends; i++)
409 gboolean exit_server(void *data)
411 DBG("exit_server Start\n");
412 if (__check_backend_status_for_exit() &&
413 __check_queue_status_for_exit()) {
414 if (!getenv("PMS_STANDALONE")) {
415 g_main_loop_quit(mainloop);
422 static int __pkgcmd_read_proc(const char *path, char *buf, int size)
426 if (buf == NULL || path == NULL)
428 fd = open(path, O_RDONLY);
431 ret = read(fd, buf, size - 1);
441 static int __pkgcmd_find_pid_by_cmdline(const char *dname,
442 const char *cmdline, const char *apppath)
446 if (strcmp(cmdline, apppath) == 0) {
448 if (pid != getpgid(pid))
454 static int __pkgcmd_proc_iter_kill_cmdline(const char *apppath, int option)
457 struct dirent *dentry;
460 char buf[1024] = {'\0'};
463 dp = opendir("/proc");
468 while ((dentry = readdir(dp)) != NULL) {
469 if (!isdigit(dentry->d_name[0]))
472 snprintf(buf, sizeof(buf), "/proc/%s/cmdline", dentry->d_name);
473 ret = __pkgcmd_read_proc(buf, buf, sizeof(buf));
477 pid = __pkgcmd_find_pid_by_cmdline(dentry->d_name, buf, apppath);
488 if (killpg(pgid, SIGKILL) < 0) {
500 static void __make_pid_info_file(char *req_key, int pid)
504 char buf[MAX_PKG_TYPE_LEN] = {0};
505 char info_file[PATH_MAX] = {'\0'};
510 snprintf(info_file, PATH_MAX, "/tmp/pkgmgr/%s", req_key);
512 DBG("info_path(%s)", info_file);
513 file = fopen(info_file, "w");
515 ERR("Couldn't open the file(%s)", info_file);
519 snprintf(buf, MAX_PKG_TYPE_LEN, "%d\n", pid);
520 fwrite(buf, 1, strlen(buf), file);
528 static int __pkgcmd_app_cb(const pkgmgrinfo_appinfo_h handle, void *user_data)
535 if (handle == NULL) {
536 perror("appinfo handle is NULL\n");
539 ret = pkgmgrinfo_appinfo_get_exec(handle, &exec);
541 perror("Failed to get app exec path\n");
544 ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid);
546 perror("Failed to get pkgid\n");
550 if (strcmp(user_data, "kill") == 0)
551 pid = __pkgcmd_proc_iter_kill_cmdline(exec, 1);
552 else if(strcmp(user_data, "check") == 0)
553 pid = __pkgcmd_proc_iter_kill_cmdline(exec, 0);
555 __make_pid_info_file(pkgid, pid);
560 void free_user_context(user_ctx* ctx)
567 //env variable ends by NULL element
577 int set_environement(user_ctx *ctx)
584 if (setgid(ctx->gid)) {
585 ERR("setgid failed: %d", errno);
588 if (setuid(ctx->uid)) {
589 ERR("setuid failed: %d", errno);
593 //env variable ends by NULL element
595 if (putenv(env[i]) != 0)
602 user_ctx* get_user_context(uid_t uid)
604 /* we can use getpwnam because this is used only after a
605 * fork and just before an execv
606 * No concurrencial call can corrupt the data
607 * returned by getpwuid
609 user_ctx *context_res;
620 context_res = (user_ctx *)malloc(sizeof(user_ctx));
625 env = (char**)malloc(3* sizeof(char *));
630 // Build environment context
631 len = snprintf(NULL,0, "HOME=%s", pwd->pw_dir);
632 env[0] = (char*)malloc((len + 1)* sizeof(char));
637 sprintf(env[0], "HOME=%s", pwd->pw_dir);
638 len = snprintf(NULL,0, "USER=%s", pwd->pw_name);
639 env[1] = (char*)malloc((len + 1)* sizeof(char));
645 sprintf(env[1], "USER=%s", pwd->pw_name);
653 //env variable ends by NULL element
654 while (env && env[i]) {
661 context_res->env = env;
662 context_res->uid = uid;
663 context_res->gid = pwd->pw_gid;
668 static char **__generate_argv(const char *args)
670 /* Create args vector
671 * req_id + pkgid + args
673 * vector size = # of args +
674 *(req_id + pkgid + NULL termination = 3)
675 * Last value must be NULL for execv.
683 ret_parse = g_shell_parse_argv(args,
684 &argcp, &argvp, &gerr);
685 if (FALSE == ret_parse) {
686 DBG("Failed to split args: %s", args);
687 DBG("messsage: %s", gerr->message);
692 for (i = 0; i < argcp; i++)
693 DBG(">>>>>> argsv[%d]=%s", i, argvp[i]);
698 void __set_environment(gpointer user_data)
700 user_ctx *ctx = (user_ctx *)user_data;
702 if (set_environement(ctx))
703 DBG("Failed to set env for the user : %d", ctx->uid);
706 static int __fork_and_exec_with_args(char **argv, uid_t uid)
708 user_ctx* user_context;
709 GError *error = NULL;
713 user_context = get_user_context(uid);
715 DBG("Failed to getenv for the user : %d", uid);
719 ret = g_spawn_async(NULL, argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD,
720 __set_environment, (gpointer)user_context, &pid,
723 ERR("Failed to excute backend: %s", error->message);
727 free_user_context(user_context);
732 void __change_item_info(pm_dbus_msg *item, uid_t uid)
736 pkgmgrinfo_appinfo_h handle = NULL;
738 ret = pkgmgrinfo_appinfo_get_usr_appinfo(item->pkgid, uid, &handle);
739 if (ret != PMINFO_R_OK)
742 ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid);
743 if (ret != PMINFO_R_OK) {
744 pkgmgrinfo_appinfo_destroy_appinfo(handle);
748 strncpy(item->appid, item->pkgid, sizeof(item->pkgid) - 1);
749 memset((item->pkgid),0,MAX_PKG_NAME_LEN);
750 strncpy(item->pkgid, pkgid, sizeof(item->pkgid) - 1);
752 pkgmgrinfo_appinfo_destroy_appinfo(handle);
755 static int __process_install(pm_dbus_msg *item)
759 char args[MAX_PKG_ARGS_LEN] = {'\0', };
762 backend_cmd = _get_backend_cmd(item->pkg_type);
763 if (backend_cmd == NULL)
766 snprintf(args, sizeof(args), "%s -k %s -i %s %s", backend_cmd,
767 item->req_id, item->pkgid, item->args);
769 argv = __generate_argv(args);
771 pid = __fork_and_exec_with_args(argv, item->uid);
778 static int __process_reinstall(pm_dbus_msg *item)
782 char args[MAX_PKG_ARGS_LEN];
785 backend_cmd = _get_backend_cmd(item->pkg_type);
786 if (backend_cmd == NULL)
789 snprintf(args, sizeof(args), "%s -k %s -r %s", backend_cmd,
790 item->req_id, item->pkgid);
791 argv = __generate_argv(args);
793 pid = __fork_and_exec_with_args(argv, item->uid);
801 static int __process_uninstall(pm_dbus_msg *item)
805 char args[MAX_PKG_ARGS_LEN];
808 backend_cmd = _get_backend_cmd(item->pkg_type);
809 if (backend_cmd == NULL)
812 snprintf(args, sizeof(args), "%s -k %s -d %s", backend_cmd,
813 item->req_id, item->pkgid);
814 argv = __generate_argv(args);
816 pid = __fork_and_exec_with_args(argv, item->uid);
824 static int __process_move(pm_dbus_msg *item)
828 char args[MAX_PKG_ARGS_LEN];
831 backend_cmd = _get_backend_cmd(item->pkg_type);
832 if (backend_cmd == NULL)
835 /* TODO: set movetype */
836 snprintf(args, sizeof(args), "%s -k %s -m %s -t %s", backend_cmd,
837 item->req_id, item->pkgid, item->args);
838 argv = __generate_argv(args);
840 pid = __fork_and_exec_with_args(argv, item->uid);
848 static int __process_enable_pkg(pm_dbus_msg *item)
854 static int __process_disable_pkg(pm_dbus_msg *item)
860 static int __process_enable_app(pm_dbus_msg *item)
864 __send_app_signal(item->uid, item->req_id, item->pkg_type, item->pkgid, item->pkgid, "start", "enable_app");
866 /* get actual pkgid and replace it to appid which is currently stored at pkgid variable */
867 __change_item_info(item, item->uid);
868 if (strlen(item->appid) == 0) {
869 __send_app_signal(item->uid, item->req_id, item->pkg_type, item->pkgid, item->pkgid, "end", "fail");
873 ret = pkgmgr_parser_update_app_disable_info_in_usr_db(item->appid, item->uid, 0);
874 if (ret != PMINFO_R_OK)
875 __send_app_signal(item->uid, item->req_id, item->pkg_type, item->pkgid, item->appid, "end", "fail");
877 __send_app_signal(item->uid, item->req_id, item->pkg_type, item->pkgid, item->appid, "end", "ok");
882 static int __process_disable_app(pm_dbus_msg *item)
886 __send_app_signal(item->uid, item->req_id, item->pkg_type, item->pkgid, item->pkgid, "start", "disable_app");
888 /* get actual pkgid and replace it to appid which is currently stored at pkgid variable */
889 __change_item_info(item, item->uid);
890 if (strlen(item->appid) == 0) {
891 __send_app_signal(item->uid, item->req_id, item->pkg_type, item->pkgid, item->pkgid, "end", "fail");
895 ret = pkgmgr_parser_update_app_disable_info_in_usr_db(item->appid, item->uid, 1);
896 if (ret != PMINFO_R_OK)
897 __send_app_signal(item->uid, item->req_id, item->pkg_type, item->pkgid, item->appid, "end", "fail");
899 __send_app_signal(item->uid, item->req_id, item->pkg_type, item->pkgid, item->appid, "end", "ok");
904 static int __process_enable_global_app_for_uid(pm_dbus_msg *item)
908 __send_app_signal(item->uid, item->req_id, item->pkg_type, item->pkgid, item->pkgid, "start", "enable_global_app_for_uid");
910 /* get actual pkgid and replace it to appid which is currently stored at pkgid variable */
911 __change_item_info(item, GLOBAL_USER);
912 if (strlen(item->appid) == 0) {
913 __send_app_signal(item->uid, item->req_id, item->pkg_type, item->pkgid, item->pkgid, "end", "fail");
917 ret = pkgmgr_parser_update_global_app_disable_for_uid_info_in_db(item->appid, item->uid, 0);
918 if (ret != PMINFO_R_OK)
919 __send_app_signal(item->uid, item->req_id, item->pkg_type, item->pkgid, item->appid, "end", "fail");
921 __send_app_signal(item->uid, item->req_id, item->pkg_type, item->pkgid, item->appid, "end", "ok");
926 static int __process_disable_global_app_for_uid(pm_dbus_msg *item)
930 __send_app_signal(item->uid, item->req_id, item->pkg_type, item->pkgid, item->pkgid, "start", "disable_global_app_for_uid");
932 /* get actual pkgid and replace it to appid which is currently stored at pkgid variable */
933 __change_item_info(item, GLOBAL_USER);
934 if (strlen(item->appid) == 0) {
935 __send_app_signal(item->uid, item->req_id, item->pkg_type, item->pkgid, item->pkgid, "end", "fail");
939 ret = pkgmgr_parser_update_global_app_disable_for_uid_info_in_db(item->appid, item->uid, 1);
940 if (ret != PMINFO_R_OK)
941 __send_app_signal(item->uid, item->req_id, item->pkg_type, item->pkgid, item->appid, "end", "fail");
943 __send_app_signal(item->uid, item->req_id, item->pkg_type, item->pkgid, item->appid, "end", "ok");
948 static int __process_getsize(pm_dbus_msg *item)
950 static const char *backend_cmd = "/usr/bin/pkg_getsize";
952 char args[MAX_PKG_ARGS_LEN];
955 snprintf(args, sizeof(args), "%s %s %s -k %s", backend_cmd, item->pkgid,
956 item->args, item->req_id);
957 argv = __generate_argv(args);
958 pid = __fork_and_exec_with_args(argv, item->uid);
965 static int __process_cleardata(pm_dbus_msg *item)
969 char args[MAX_PKG_ARGS_LEN];
972 backend_cmd = _get_backend_cmd(item->pkg_type);
973 if (backend_cmd == NULL)
976 /* TODO: set movetype */
977 snprintf(args, sizeof(args), "%s -k %s -c %s", backend_cmd,
978 item->req_id, item->pkgid);
979 argv = __generate_argv(args);
981 pid = __fork_and_exec_with_args(argv, item->uid);
989 static int __process_clearcache(pm_dbus_msg *item)
991 static const char *backend_cmd = "/usr/bin/pkg_clearcache";
993 char args[MAX_PKG_ARGS_LEN];
996 snprintf(args, sizeof(args), "%s %s", backend_cmd, item->pkgid);
997 argv = __generate_argv(args);
998 pid = __fork_and_exec_with_args(argv, item->uid);
1005 static int __process_kill(pm_dbus_msg *item)
1008 pkgmgrinfo_pkginfo_h handle;
1010 ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(item->pkgid, item->uid,
1013 ERR("Failed to get handle");
1017 ret = pkgmgrinfo_appinfo_get_usr_list(handle, PMINFO_ALL_APP,
1018 __pkgcmd_app_cb, "kill", item->uid);
1019 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1021 ERR("pkgmgrinfo_appinfo_get_list() failed");
1028 static int __process_check(pm_dbus_msg *item)
1031 pkgmgrinfo_pkginfo_h handle;
1033 ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(item->pkgid, item->uid,
1036 ERR("Failed to get handle");
1040 ret = pkgmgrinfo_appinfo_get_usr_list(handle, PMINFO_ALL_APP,
1041 __pkgcmd_app_cb, "check", item->uid);
1042 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1044 ERR("pkgmgrinfo_appinfo_get_list() failed");
1051 static int __process_generate_license_request(pm_dbus_msg *item)
1055 char req_data[MAX_PKG_ARGS_LEN];
1056 unsigned int req_data_len;
1057 char license_url[MAX_PKG_ARGS_LEN];
1058 unsigned int license_url_len;
1060 resp_data = item->args;
1061 req_data_len = sizeof(req_data);
1062 license_url_len = sizeof(license_url);
1064 ret = drm_tizen_generate_license_request(resp_data, strlen(resp_data),
1065 req_data, &req_data_len, license_url, &license_url_len);
1066 if (ret != TADC_SUCCESS) {
1067 ERR("drm_tizen_generate_license_request failed: %d", ret);
1068 __return_value_to_caller(item->req_id, g_variant_new("(iss)",
1069 PKGMGR_R_ESYSTEM, "", ""));
1073 __return_value_to_caller(item->req_id,
1074 g_variant_new("(iss)", PKGMGR_R_OK, req_data,
1080 static int __process_register_license(pm_dbus_msg *item)
1085 resp_data = item->args;
1087 ret = drm_tizen_register_license(resp_data, strlen(resp_data));
1088 if (ret != TADC_SUCCESS) {
1089 ERR("drm_tizen_register_license failed: %d", ret);
1090 __return_value_to_caller(item->req_id,
1091 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1095 __return_value_to_caller(item->req_id,
1096 g_variant_new("(i)", PKGMGR_R_OK));
1101 static int __process_decrypt_package(pm_dbus_msg *item)
1104 char *drm_file_path;
1105 char *decrypted_file_path;
1107 drm_file_path = item->pkgid;
1108 decrypted_file_path = item->args;
1110 /* TODO: check ownership of decrypted file */
1111 ret = drm_tizen_decrypt_package(drm_file_path, strlen(drm_file_path),
1112 decrypted_file_path, strlen(decrypted_file_path));
1113 if (ret != TADC_SUCCESS) {
1114 ERR("drm_tizen_register_license failed: %d", ret);
1115 __return_value_to_caller(item->req_id,
1116 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1120 __return_value_to_caller(item->req_id,
1121 g_variant_new("(i)", PKGMGR_R_OK));
1126 static int __process_add_blacklist(pm_dbus_msg *item)
1130 ret = __add_blacklist(item->uid, item->pkgid);
1132 __return_value_to_caller(item->req_id,
1133 g_variant_new("(i)", ret));
1138 static int __process_remove_blacklist(pm_dbus_msg *item)
1142 ret = __remove_blacklist(item->uid, item->pkgid);
1144 __return_value_to_caller(item->req_id,
1145 g_variant_new("(i)", ret));
1150 static int __process_check_blacklist(pm_dbus_msg *item)
1155 ret = __check_blacklist(item->uid, item->pkgid, &result);
1157 __return_value_to_caller(item->req_id,
1158 g_variant_new("(ii)", result, ret));
1163 gboolean queue_job(void *data)
1165 pm_dbus_msg *item = NULL;
1170 /* Pop a job from queue */
1171 for (x = 0, ptr = begin; x < num_of_backends; x++, ptr++) {
1172 if (__is_backend_busy(x))
1175 item = _pm_queue_pop(x);
1176 if (item && item->req_type != -1)
1181 /* all backend messages queue are empty or busy */
1182 if (x == num_of_backends)
1185 /*save pkg type and pkg name for future*/
1186 strncpy(ptr->pkgtype, item->pkg_type, MAX_PKG_TYPE_LEN-1);
1187 strncpy(ptr->pkgid, item->pkgid, MAX_PKG_NAME_LEN-1);
1188 strncpy(ptr->args, item->args, MAX_PKG_ARGS_LEN-1);
1189 memset((item->appid),0,MAX_PKG_NAME_LEN);
1190 ptr->uid = item->uid;
1191 DBG("handle request type [%d]", ptr->pid, item->req_type);
1193 switch (item->req_type) {
1194 case PKGMGR_REQUEST_TYPE_INSTALL:
1195 __set_backend_busy(x);
1196 __set_recovery_mode(item->uid, item->pkgid, item->pkg_type);
1197 ret = __process_install(item);
1199 case PKGMGR_REQUEST_TYPE_REINSTALL:
1200 __set_backend_busy(x);
1201 __set_recovery_mode(item->uid, item->pkgid, item->pkg_type);
1202 ret = __process_reinstall(item);
1204 case PKGMGR_REQUEST_TYPE_UNINSTALL:
1205 __set_backend_busy(x);
1206 __set_recovery_mode(item->uid, item->pkgid, item->pkg_type);
1207 ret = __process_uninstall(item);
1209 case PKGMGR_REQUEST_TYPE_MOVE:
1210 __set_backend_busy(x);
1211 __set_recovery_mode(item->uid, item->pkgid, item->pkg_type);
1212 ret = __process_move(item);
1214 case PKGMGR_REQUEST_TYPE_ENABLE_PKG:
1215 ret = __process_enable_pkg(item);
1217 case PKGMGR_REQUEST_TYPE_DISABLE_PKG:
1218 ret = __process_disable_pkg(item);
1220 case PKGMGR_REQUEST_TYPE_ENABLE_APP:
1221 ret = __process_enable_app(item);
1223 case PKGMGR_REQUEST_TYPE_DISABLE_APP:
1224 ret = __process_disable_app(item);
1226 case PKGMGR_REQUEST_TYPE_GETSIZE:
1227 __set_backend_busy(x);
1228 ret = __process_getsize(item);
1230 case PKGMGR_REQUEST_TYPE_CLEARDATA:
1231 __set_backend_busy(x);
1232 ret = __process_cleardata(item);
1234 case PKGMGR_REQUEST_TYPE_CLEARCACHE:
1235 __set_backend_busy(x);
1236 ret = __process_clearcache(item);
1238 case PKGMGR_REQUEST_TYPE_ENABLE_GLOBAL_APP_FOR_UID:
1239 ret = __process_enable_global_app_for_uid(item);
1241 case PKGMGR_REQUEST_TYPE_DISABLE_GLOBAL_APP_FOR_UID:
1242 ret = __process_disable_global_app_for_uid(item);
1244 case PKGMGR_REQUEST_TYPE_KILL:
1245 ret = __process_kill(item);
1247 case PKGMGR_REQUEST_TYPE_CHECK:
1248 ret = __process_check(item);
1250 case PKGMGR_REQUEST_TYPE_GENERATE_LICENSE_REQUEST:
1251 ret = __process_generate_license_request(item);
1253 case PKGMGR_REQUEST_TYPE_REGISTER_LICENSE:
1254 ret = __process_register_license(item);
1256 case PKGMGR_REQUEST_TYPE_DECRYPT_PACKAGE:
1257 ret = __process_decrypt_package(item);
1259 case PKGMGR_REQUEST_TYPE_ADD_BLACKLIST:
1260 ret = __process_add_blacklist(item);
1262 case PKGMGR_REQUEST_TYPE_REMOVE_BLACKLIST:
1263 ret = __process_remove_blacklist(item);
1265 case PKGMGR_REQUEST_TYPE_CHECK_BLACKLIST:
1266 ret = __process_check_blacklist(item);
1279 #define IS_WHITESPACE(CHAR) \
1280 ((CHAR == ' ' || CHAR == '\t' || CHAR == '\r' || CHAR == '\n') ? TRUE : FALSE)
1282 void _app_str_trim(char *input)
1284 char *trim_str = input;
1289 while (*input != 0) {
1290 if (!IS_WHITESPACE(*input)) {
1301 char *_get_backend_cmd(char *type)
1304 char buffer[1024] = { 0 };
1305 char *command = NULL;
1307 fp = fopen(PKG_CONF_PATH, "r");
1313 while (fgets(buffer, 1024, fp) != NULL) {
1314 if (buffer[0] == '#')
1317 _app_str_trim(buffer);
1319 if ((path = strstr(buffer, PKG_BACKEND)) != NULL) {
1320 DBG("buffer [%s]", buffer);
1321 path = path + strlen(PKG_BACKEND);
1322 DBG("path [%s]", path);
1325 (char *)malloc(sizeof(char) * strlen(path) +
1327 if (command == NULL) {
1332 size = strlen(path) + strlen(type) + 1;
1333 snprintf(command, size, "%s%s", path, type);
1334 command[strlen(path) + strlen(type)] = '\0';
1335 DBG("command [%s]", command);
1343 memset(buffer, 0x00, 1024);
1349 return NULL; /* cannot find proper command */
1352 int main(int argc, char *argv[])
1354 FILE *fp_status = NULL;
1355 char buf[32] = { 0, };
1357 char *backend_cmd = NULL;
1358 char *backend_name = NULL;
1361 DBG("server start");
1363 if (argv[1] && (strcmp(argv[1], "init") == 0)) {
1364 /* if current status is "processing",
1365 execute related backend with '-r' option */
1366 if (!(fp_status = fopen(STATUS_FILE, "r")))
1367 return 0; /*if file is not exist, terminated. */
1368 /* if processing <-- unintended termination */
1369 if (fgets(buf, 32, fp_status) &&
1370 strcmp(buf, "processing") == 0) {
1372 if (pid == 0) { /* child */
1373 if (fgets(buf, 32, fp_status))
1374 backend_cmd = _get_backend_cmd(buf);
1375 if (!backend_cmd) { /* if NULL, */
1376 DBG("fail to get backend command");
1380 strrchr(backend_cmd, '/');
1381 if (!backend_name) {
1382 DBG("fail to get backend name");
1386 execl(backend_cmd, backend_name, "-r",
1390 fprintf(fp_status, " ");
1394 } else if (pid < 0) { /* error */
1398 } else { /* parent */
1400 DBG("parent end\n");
1401 fprintf(fp_status, " ");
1408 r = _pm_queue_init();
1410 DBG("Queue Initialization Failed\n");
1414 r = __init_backend_info();
1416 DBG("backend info init failed");
1420 r = __init_request_handler();
1422 ERR("dbus init failed");
1426 if (__register_signal_handler()) {
1427 ERR("failed to register signal handler");
1431 #if !GLIB_CHECK_VERSION(2,35,0)
1434 mainloop = g_main_loop_new(NULL, FALSE);
1436 ERR("g_main_loop_new failed");
1440 DBG("Main loop is created.");
1442 g_main_loop_run(mainloop);
1444 DBG("Quit main loop.");
1445 __fini_request_handler();
1446 __fini_backend_info();
1449 DBG("package manager server terminated.");