Kill app using aul api instead of proc filesystem
[platform/core/appfw/pkgmgr-server.git] / src / pkgmgr-server.c
1 /*
2  * slp-pkgmgr
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
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>
8  *
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
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
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.
20  *
21  */
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <ctype.h>
27 #include <unistd.h>
28 #include <pwd.h>
29 #include <sys/types.h>
30 #include <sys/wait.h>
31 #include <sys/stat.h>
32 #include <sys/types.h>
33 #include <fcntl.h>
34 #include <signal.h>
35 #include <grp.h>
36
37 #include <glib.h>
38 #include <gio/gio.h>
39
40 #include <aul.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>
47 #endif
48
49 #include "pkgmgr_installer.h"
50 #include "pkgmgr-server.h"
51 #include "pm-queue.h"
52 #include "package-manager.h"
53
54 #define BUFMAX 128
55 #define NO_MATCHING_FILE 11
56
57 #define OWNER_ROOT 0
58 #define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
59 #define APPFW_UID 301
60
61
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]))
66
67 typedef struct  {
68         char **env;
69         uid_t uid;
70         gid_t gid;
71 } user_ctx;
72
73 typedef struct {
74         uid_t uid;
75         char *cmd;
76 } pkgcmd_data;
77
78 /*
79 8 bit value to represent maximum 8 backends.
80 Each bit position corresponds to a queue slot which
81 is dynamically determined.
82 */
83 char backend_busy = 0;
84 extern int num_of_backends;
85
86 struct signal_info_t {
87         pid_t pid;
88         int status;
89 };
90
91 static int pipe_sig[2];
92 static GIOChannel *pipe_io;
93 static guint pipe_wid;
94
95 backend_info *begin;
96 extern queue_info_map *start;
97 extern int entries;
98
99 GMainLoop *mainloop = NULL;
100
101
102 /* operation_type */
103 typedef enum {
104         OPERATION_INSTALL = 0,
105         OPERATION_UNINSTALL,
106         OPERATION_ACTIVATE,
107         OPERATION_REINSTALL,
108         OPERATION_MAX
109 } OPERATION_TYPE;
110
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);
117
118 gboolean exit_server(void *data);
119
120 /* To check whether a particular backend is free/busy*/
121 static int __is_backend_busy(int position)
122 {
123         return backend_busy & 1<<position;
124 }
125 /*To set a particular backend as busy*/
126 static void __set_backend_busy(int position)
127 {
128         backend_busy = backend_busy | 1<<position;
129 }
130 /*To set a particular backend as free */
131 static void __set_backend_free(int position)
132 {
133         backend_busy = backend_busy & ~(1<<position);
134 }
135
136 static gboolean pipe_io_handler(GIOChannel *io, GIOCondition cond, gpointer data)
137 {
138         int x;
139         GError *err = NULL;
140         GIOStatus s;
141         gsize len;
142         struct signal_info_t info;
143         backend_info *ptr = begin;
144
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);
148                 g_error_free(err);
149                 return TRUE;
150         }
151
152         for (x = 0; x < num_of_backends; x++, ptr++) {
153                 if (ptr && ptr->pid == info.pid)
154                         break;
155         }
156
157         if (x == num_of_backends) {
158                 ERR("Unknown child exit");
159                 return -1;
160         }
161
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);
169         } else {
170                 DBG("backend[%s] exit", ptr->pkgtype);
171         }
172
173         g_idle_add(queue_job, NULL);
174
175         return TRUE;
176 }
177
178 static int __init_backend_info(void)
179 {
180         backend_info *ptr;
181
182         /*Allocate memory for holding pid, pkgtype and pkgid*/
183         ptr = (backend_info*)calloc(num_of_backends, sizeof(backend_info));
184         if (ptr == NULL) {
185                 DBG("Malloc Failed\n");
186                 return -1;
187         }
188         begin = ptr;
189
190         if (pipe(pipe_sig)) {
191                 ERR("create pipe failed");
192                 return -1;
193         }
194
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);
199
200         return 0;
201 }
202
203 static void __fini_backend_info(void)
204 {
205         g_source_remove(pipe_wid);
206         g_io_channel_unref(pipe_io);
207         close(pipe_sig[0]);
208         close(pipe_sig[1]);
209
210         /*Free backend info */
211         free(begin);
212 }
213
214 static void sighandler(int signo)
215 {
216         struct signal_info_t info;
217         char buf[1024] = {0, };
218
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)));
222 }
223
224 static int __register_signal_handler(void)
225 {
226         static int sig_reg = 0;
227         struct sigaction act;
228
229         if (sig_reg)
230                 return 0;
231
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");
237                 return -1;
238         }
239
240         g_timeout_add_seconds(2, exit_server, NULL);
241
242         sig_reg = 1;
243         return 0;
244 }
245
246 static int __check_backend_status_for_exit(void)
247 {
248         int i = 0;
249         for (i = 0; i < num_of_backends; i++) {
250                 if (__is_backend_busy(i))
251                         return 0;
252         }
253         return 1;
254 }
255
256 static int __check_queue_status_for_exit(void)
257 {
258         pm_queue_data *head[MAX_QUEUE_NUM] = {NULL,};
259         queue_info_map *ptr = NULL;
260         ptr = start;
261         int i = 0;
262         int c = 0;
263         int slot = -1;
264         for (i = 0; i < entries; i++) {
265                 if (ptr->queue_slot <= slot) {
266                         ptr++;
267                 } else {
268                         head[c] = ptr->head;
269                         slot = ptr->queue_slot;
270                         c++;
271                         ptr++;
272                 }
273         }
274         for (i = 0; i < num_of_backends; i++) {
275                 if (head[i])
276                         return 0;
277         }
278         return 1;
279 }
280
281 gboolean exit_server(void *data)
282 {
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);
288                         return FALSE;
289                 }
290         }
291         return TRUE;
292 }
293
294 #ifdef TIZEN_FEATURE_CSR
295 static int __check_csr(backend_info *ptr)
296 {
297         csr_cs_context_h context = NULL;
298         csr_cs_malware_h detected = NULL;
299         int ret = -1;
300
301         ret = csr_cs_context_create(&context);
302         if (ret != CSR_ERROR_NONE) {
303                 ERR("Failed to create csr context");
304                 return -1;
305         }
306
307         if (context) {
308                 ret = csr_cs_scan_file(context, ptr->pkgid, &detected);
309                 DBG("CSR result[%d]", ret);
310
311                 csr_cs_context_destroy(context);
312                 if (detected != NULL) {
313                         ERR("CSR Denied[%s] Installation", ptr->pkgid);
314                         return -1;
315                 }
316         }
317
318         return 0;
319 }
320 #endif
321
322 static void __make_pid_info_file(char *req_key, int pid, uid_t uid)
323 {
324         FILE* file;
325         int fd;
326         int ret;
327         char buf[MAX_PKG_TYPE_LEN] = {0};
328         char info_file[PATH_MAX] = {'\0'};
329         struct passwd pwd;
330         struct passwd *pwd_result;
331
332         if (req_key == NULL)
333                 return;
334
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);
338                 return;
339         }
340         DBG("uid(%d), gid(%d)", uid, pwd.pw_gid);
341
342         snprintf(info_file, PATH_MAX, "/tmp/pkgmgr/%s", req_key);
343
344         DBG("info_path(%s)", info_file);
345         file = fopen(info_file, "w");
346         if (file == NULL) {
347                 ERR("Couldn't open the file(%s)", info_file);
348                 return;
349         }
350
351         snprintf(buf, MAX_PKG_TYPE_LEN, "%d\n", pid);
352         fwrite(buf, 1, strlen(buf), file);
353
354         fflush(file);
355         fd = fileno(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);
360         fsync(fd);
361         fclose(file);
362 }
363
364 static int __kill_app(char *appid, uid_t uid)
365 {
366         int ret;
367         int pid;
368         int is_running;
369
370         is_running = aul_app_is_running_for_uid(appid, uid);
371         /* app is not running */
372         if (!is_running)
373                 return 0;
374
375         pid = aul_app_get_pid_for_uid(appid, uid);
376         if (pid == -1)
377                 return -1;
378
379         ret = aul_terminate_pid_for_uid(pid, uid);
380         if (ret != AUL_R_OK) {
381                 ERR("failed to terminate app(%d)", appid);
382                 return -1;
383         }
384
385         return 0;
386 }
387
388 static int __check_app(char *appid, uid_t uid)
389 {
390         int pid;
391         int is_running;
392
393         is_running = aul_app_is_running_for_uid(appid, uid);
394         if (!is_running)
395                 return 0;
396
397         pid = aul_app_get_pid_for_uid(appid, uid);
398
399         return pid;
400 }
401
402 static int __pkgcmd_app_cb(const pkgmgrinfo_appinfo_h handle, void *user_data)
403 {
404         char *pkgid;
405         char *appid;
406         char *exec;
407         int ret;
408         int pid = -1;
409         pkgcmd_data *pdata = (pkgcmd_data *)user_data;
410
411         if (handle == NULL) {
412                 perror("appinfo handle is NULL\n");
413                 exit(1);
414         }
415         ret = pkgmgrinfo_appinfo_get_exec(handle, &exec);
416         if (ret) {
417                 perror("Failed to get app exec path\n");
418                 exit(1);
419         }
420         ret = pkgmgrinfo_appinfo_get_appid(handle, &appid);
421         if (ret) {
422                 perror("Failed to get appid\n");
423                 exit(1);
424         }
425         ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid);
426         if (ret) {
427                 perror("Failed to get pkgid\n");
428                 exit(1);
429         }
430
431         if (strcmp(pdata->cmd, "kill") == 0) {
432                 pid = __check_app(appid, pdata->uid);
433                 if (pid > 0)
434                         ret = __kill_app(appid, pdata->uid);
435         } else if (strcmp(pdata->cmd, "check") == 0) {
436                 pid = __check_app(appid, pdata->uid);
437         }
438
439         __make_pid_info_file(pkgid, pid, pdata->uid);
440
441         return 0;
442 }
443
444 void free_user_context(user_ctx* ctx)
445 {
446         char **env = NULL;
447         int i = 0;
448         if (!ctx)
449                 return;
450         env = ctx->env;
451         /* env variable ends by NULL element */
452         while (env[i]) {
453                 free(env[i]);
454                 i++;
455         }
456         free(env);
457         env = NULL;
458         free(ctx);
459 }
460
461 int set_environement(user_ctx *ctx)
462 {
463         int i = 0;
464         int res = 0;
465         char **env = NULL;
466         int n;
467         gid_t *groups;
468
469         if (!ctx)
470                 return -1;
471
472         if (ctx->uid != APPFW_UID) {
473                 if (setuid(ctx->uid)) {
474                         ERR("setuid failed: %d", errno);
475                         return -1;
476                 }
477
478                 if (setgid(ctx->gid)) {
479                         ERR("setgid failed: %d", errno);
480                         return -1;
481                 }
482         }
483
484         n = getgroups(0, NULL);
485         if (n < 0) {
486                 ERR("Failed to get the number of supplementary group IDs");
487                 return -1;
488         }
489
490         groups = (gid_t *)calloc(1, sizeof(gid_t) * (n + 3));
491         if (groups == NULL) {
492                 ERR("out of memory");
493                 return -1;
494         }
495
496         n = getgroups(n, groups);
497         if (n < 0) {
498                 ERR("Failed to get list of supplementary group IDs");
499                 free(groups);
500                 return -1;
501         }
502
503         groups[n++] = EXT_STORAGE_GROUP;
504         groups[n++] = EXT_STORAGE_APPDATA_GROUP;
505         groups[n++] = MEDIA_STORAGE_GROUP;
506
507         if (setgroups(n, groups) < 0) {
508                 ERR("setgroups failed: %d", errno);
509                 free(groups);
510                 return -1;
511         }
512         free(groups);
513
514         env = ctx->env;
515         /* env variable ends by NULL element */
516         while (env[i]) {
517                 if (putenv(env[i]) != 0)
518                         res = -1;
519                 i++;
520         }
521         return res;
522 }
523
524 user_ctx *get_user_context(uid_t uid)
525 {
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
530          */
531         user_ctx *context_res;
532         char **env = NULL;
533         char buf[1024] = {0, };
534         struct passwd pwd, *result;
535         int len;
536         int ret = 0;
537         int i;
538
539         ret = getpwuid_r(uid, &pwd, buf, sizeof(buf), &result);
540         if (ret != 0 || result == NULL)
541                 return NULL;
542
543         do {
544                 context_res = (user_ctx *)malloc(sizeof(user_ctx));
545                 if (!context_res) {
546                         ret = -1;
547                         break;
548                 }
549                 env = (char **)malloc(3 * sizeof(char *));
550                 if (!env) {
551                         ret = -1;
552                         break;
553                 }
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) {
558                         ret = -1;
559                         break;
560                 }
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) {
565                         ret = -1;
566                         break;
567                 }
568                 snprintf(env[1], len + 1, "USER=%s", pwd.pw_name);
569                 env[2] = NULL;
570         } while (0);
571
572         if (ret == -1) {
573                 free(context_res);
574                 context_res = NULL;
575                 i = 0;
576                 /* env variable ends by NULL element */
577                 while (env && env[i]) {
578                         free(env[i]);
579                         i++;
580                 }
581                 free(env);
582                 env = NULL;
583         } else {
584                 context_res->env = env;
585                 context_res->uid = uid;
586                 context_res->gid = pwd.pw_gid;
587         }
588         return context_res;
589 }
590
591 static char **__generate_argv(const char *args)
592 {
593         /* Create args vector
594          * req_id + pkgid + args
595          *
596          * vector size = # of args +
597          *(req_id + pkgid + NULL termination = 3)
598          * Last value must be NULL for execv.
599          */
600         gboolean ret_parse;
601         gint argcp;
602         gchar **argvp;
603         GError *gerr = NULL;
604         int i;
605
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);
610                 exit(1);
611         }
612
613         /* dbg */
614         for (i = 0; i < argcp; i++)
615                 DBG(">>>>>> argsv[%d]=%s", i, argvp[i]);
616
617         return argvp;
618 }
619
620 void __set_environment(gpointer user_data)
621 {
622         user_ctx *ctx = (user_ctx *)user_data;
623
624         if (set_environement(ctx))
625                 DBG("Failed to set env for the user : %d", ctx->uid);
626 }
627
628 static int __fork_and_exec_with_args(char **argv, uid_t uid)
629 {
630         user_ctx* user_context;
631         GError *error = NULL;
632         gboolean ret;
633         int pid;
634
635         user_context = get_user_context(uid);
636         if (!user_context) {
637                 DBG("Failed to getenv");
638                 return -1;
639         }
640
641         ret = g_spawn_async(NULL, argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD,
642                         __set_environment, (gpointer)user_context, &pid,
643                         &error);
644         if (ret != TRUE) {
645                 ERR("Failed to excute backend: %s", error->message);
646                 g_error_free(error);
647         }
648
649         free_user_context(user_context);
650
651         return pid;
652 }
653
654 static int __change_item_info(pm_dbus_msg *item, uid_t uid, bool *is_global)
655 {
656         int ret = 0;
657         char *pkgid = NULL;
658         pkgmgrinfo_appinfo_h handle = NULL;
659
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);
666                 break;
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);
670                 break;
671         default:
672                 return PMINFO_R_ERROR;
673         }
674
675         if (ret != PMINFO_R_OK)
676                 return PMINFO_R_ERROR;
677
678         ret = pkgmgrinfo_appinfo_is_global(handle, is_global);
679         if (ret != PMINFO_R_OK)
680                 goto catch;
681
682         if ((item->req_type == PKGMGR_REQUEST_TYPE_DISABLE_APP
683                         || item->req_type == PKGMGR_REQUEST_TYPE_ENABLE_APP)
684                         && *is_global) {
685                         ret = PMINFO_R_ERROR;
686                         goto catch;
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)
689                         && !*is_global) {
690                         ret = PMINFO_R_ERROR;
691                         goto catch;
692         }
693
694         ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid);
695         if (ret != PMINFO_R_OK)
696                 goto catch;
697
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);
701
702 catch:
703         pkgmgrinfo_appinfo_destroy_appinfo(handle);
704
705         return ret;
706 }
707
708 static int __process_install(pm_dbus_msg *item)
709 {
710         char *backend_cmd;
711         char **argv;
712         char args[MAX_PKG_ARGS_LEN] = {'\0', };
713         int pid;
714
715         backend_cmd = _get_backend_cmd(item->pkg_type);
716         if (backend_cmd == NULL)
717                 return -1;
718
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);
721
722         argv = __generate_argv(args);
723
724         pid = __fork_and_exec_with_args(argv, APPFW_UID);
725         g_strfreev(argv);
726         free(backend_cmd);
727
728         return pid;
729 }
730
731 static int __process_mount_install(pm_dbus_msg *item)
732 {
733         char *backend_cmd;
734         char **argv;
735         char args[MAX_PKG_ARGS_LEN] = {'\0', };
736         int pid;
737
738         backend_cmd = _get_backend_cmd(item->pkg_type);
739         if (backend_cmd == NULL)
740                 return -1;
741
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);
744
745         argv = __generate_argv(args);
746
747         pid = __fork_and_exec_with_args(argv, APPFW_UID);
748         g_strfreev(argv);
749         free(backend_cmd);
750
751         return pid;
752 }
753
754 static int __process_reinstall(pm_dbus_msg *item)
755 {
756         char *backend_cmd;
757         char **argv;
758         char args[MAX_PKG_ARGS_LEN];
759         int pid;
760
761         backend_cmd = _get_backend_cmd(item->pkg_type);
762         if (backend_cmd == NULL)
763                 return -1;
764
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);
768
769         pid = __fork_and_exec_with_args(argv, APPFW_UID);
770
771         g_strfreev(argv);
772         free(backend_cmd);
773
774         return pid;
775 }
776
777 static int __process_uninstall(pm_dbus_msg *item)
778 {
779         char *backend_cmd;
780         char **argv;
781         char args[MAX_PKG_ARGS_LEN];
782         int pid;
783
784         backend_cmd = _get_backend_cmd(item->pkg_type);
785         if (backend_cmd == NULL)
786                 return -1;
787
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);
791
792         pid = __fork_and_exec_with_args(argv, APPFW_UID);
793
794         g_strfreev(argv);
795         free(backend_cmd);
796
797         return pid;
798 }
799
800 static int __process_move(pm_dbus_msg *item)
801 {
802         char *backend_cmd;
803         char **argv;
804         char args[MAX_PKG_ARGS_LEN];
805         int pid;
806
807         backend_cmd = _get_backend_cmd(item->pkg_type);
808         if (backend_cmd == NULL)
809                 return -1;
810
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);
814
815         pid = __fork_and_exec_with_args(argv, APPFW_UID);
816
817         g_strfreev(argv);
818         free(backend_cmd);
819
820         return pid;
821 }
822
823 static int __process_enable_pkg(pm_dbus_msg *item)
824 {
825         char *backend_cmd;
826         char **argv;
827         char args[MAX_PKG_ARGS_LEN];
828         int pid;
829
830         backend_cmd = _get_backend_cmd(item->pkg_type);
831         if (backend_cmd == NULL)
832                 return -1;
833
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);
837
838         pid = __fork_and_exec_with_args(argv, APPFW_UID);
839
840         g_strfreev(argv);
841         free(backend_cmd);
842
843         return pid;
844 }
845
846 static int __process_disable_pkg(pm_dbus_msg *item)
847 {
848         char *backend_cmd;
849         char **argv;
850         char args[MAX_PKG_ARGS_LEN];
851         int pid;
852
853         backend_cmd = _get_backend_cmd(item->pkg_type);
854         if (backend_cmd == NULL)
855                 return -1;
856
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);
860
861         pid = __fork_and_exec_with_args(argv, APPFW_UID);
862
863         g_strfreev(argv);
864         free(backend_cmd);
865
866         return pid;
867 }
868
869 static int __process_enable_app(pm_dbus_msg *item)
870 {
871         int ret = -1;
872         bool is_global = false;
873
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,
882                                 item->req_type);
883                 return ret;
884         }
885
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);
889
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,
894                                 item->req_type);
895         else
896                 __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
897                                 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_OK_EVENT_STR,
898                                 item->req_type);
899
900
901         return ret;
902 }
903
904 static int __process_disable_app(pm_dbus_msg *item)
905 {
906         int ret = -1;
907         bool is_global = false;
908
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,
917                                 item->req_type);
918                 return ret;
919         }
920
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);
924
925         ret = __kill_app(item->appid, item->uid);
926         if (ret != 0) {
927                 __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
928                                 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_FAIL_EVENT_STR,
929                                 item->req_type);
930         }
931
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,
936                                 item->req_type);
937         else
938                 __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
939                                 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_OK_EVENT_STR,
940                                 item->req_type);
941
942         return ret;
943 }
944
945 static int __process_enable_global_app_for_uid(pm_dbus_msg *item)
946 {
947         int ret = -1;
948         bool is_global = true;
949
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,
958                                 item->req_type);
959                 return ret;
960         }
961
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);
965
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,
970                                 item->req_type);
971         else
972                 __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
973                                 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_OK_EVENT_STR,
974                                 item->req_type);
975
976         return ret;
977 }
978
979 static int __process_disable_global_app_for_uid(pm_dbus_msg *item)
980 {
981         int ret = -1;
982         bool is_global = true;
983
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,
993                                 item->req_type);
994                 return ret;
995         }
996
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);
1001
1002         ret = __kill_app(item->appid, item->uid);
1003         ret = pkgmgr_parser_update_global_app_disable_for_uid_info_in_db(item->appid,
1004                 item->uid, 1);
1005
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,
1009                                 item->req_type);
1010         else
1011                 __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
1012                                 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_OK_EVENT_STR,
1013                                 item->req_type);
1014
1015         return ret;
1016 }
1017
1018 static int __process_getsize(pm_dbus_msg *item)
1019 {
1020         static const char *backend_cmd = "/usr/bin/pkg_getsize";
1021         char **argv;
1022         char args[MAX_PKG_ARGS_LEN];
1023         int pid;
1024
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);
1029
1030         g_strfreev(argv);
1031
1032         return pid;
1033 }
1034
1035 static int __process_cleardata(pm_dbus_msg *item)
1036 {
1037         char *backend_cmd;
1038         char **argv;
1039         char args[MAX_PKG_ARGS_LEN];
1040         int pid;
1041
1042         backend_cmd = _get_backend_cmd(item->pkg_type);
1043         if (backend_cmd == NULL)
1044                 return -1;
1045
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);
1050
1051         pid = __fork_and_exec_with_args(argv, APPFW_UID);
1052
1053         g_strfreev(argv);
1054         free(backend_cmd);
1055
1056         return pid;
1057 }
1058
1059 static int __process_clearcache(pm_dbus_msg *item)
1060 {
1061         static const char *backend_cmd = "/usr/bin/pkg_clearcache";
1062         char **argv;
1063         char args[MAX_PKG_ARGS_LEN];
1064         int pid;
1065
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);
1069
1070         g_strfreev(argv);
1071
1072         return pid;
1073 }
1074
1075 static int __process_kill(pm_dbus_msg *item)
1076 {
1077         int ret;
1078         pkgmgrinfo_pkginfo_h handle;
1079         pkgcmd_data *pdata = NULL;
1080
1081         ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(item->pkgid, item->uid,
1082                         &handle);
1083         if (ret < 0) {
1084                 ERR("Failed to get handle");
1085                 return -1;
1086         }
1087
1088         pdata = calloc(1, sizeof(pkgcmd_data));
1089         if (pdata == NULL) {
1090                 ERR("memory alloc failed");
1091                 return -1;
1092         }
1093         pdata->cmd = strdup("kill");
1094         if (pdata->cmd == NULL) {
1095                 ERR("out of memory");
1096                 free(pdata);
1097                 pdata = NULL;
1098                 return -1;
1099         }
1100         pdata->uid = item->uid;
1101         ret = pkgmgrinfo_appinfo_get_usr_list(handle, PMINFO_ALL_APP,
1102                         __pkgcmd_app_cb, pdata, item->uid);
1103         free(pdata->cmd);
1104         free(pdata);
1105         pdata = NULL;
1106         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1107         if (ret < 0) {
1108                 ERR("pkgmgrinfo_appinfo_get_list() failed");
1109                 return -1;
1110         }
1111
1112         return 0;
1113 }
1114
1115 static int __process_check(pm_dbus_msg *item)
1116 {
1117         int ret;
1118         pkgmgrinfo_pkginfo_h handle;
1119         pkgcmd_data *pdata = NULL;
1120
1121         ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(item->pkgid, item->uid,
1122                         &handle);
1123         if (ret < 0) {
1124                 ERR("Failed to get handle");
1125                 return -1;
1126         }
1127
1128         pdata = calloc(1, sizeof(pkgcmd_data));
1129         if (pdata == NULL) {
1130                 ERR("memory alloc failed");
1131                 return -1;
1132         }
1133         pdata->cmd = strdup("check");
1134         if (pdata->cmd == NULL) {
1135                 ERR("out of memory");
1136                 free(pdata);
1137                 pdata = NULL;
1138                 return -1;
1139         }
1140         pdata->uid = item->uid;
1141         ret = pkgmgrinfo_appinfo_get_usr_list(handle, PMINFO_ALL_APP,
1142                         __pkgcmd_app_cb, pdata, item->uid);
1143         free(pdata->cmd);
1144         free(pdata);
1145         pdata = NULL;
1146         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1147         if (ret < 0) {
1148                 ERR("pkgmgrinfo_appinfo_get_list() failed");
1149                 return -1;
1150         }
1151
1152         return 0;
1153 }
1154
1155 static int __process_generate_license_request(pm_dbus_msg *item)
1156 {
1157         int ret;
1158         char *resp_data;
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;
1163
1164         resp_data = item->args;
1165         req_data_len = sizeof(req_data);
1166         license_url_len = sizeof(license_url);
1167
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, "", ""));
1174                 return -1;
1175         }
1176
1177         __return_value_to_caller(item->req_id,
1178                         g_variant_new("(iss)", PKGMGR_R_OK, req_data,
1179                                 license_url));
1180
1181         return 0;
1182 }
1183
1184 static int __process_register_license(pm_dbus_msg *item)
1185 {
1186         int ret;
1187         char *resp_data;
1188
1189         resp_data = item->args;
1190
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));
1196                 return -1;
1197         }
1198
1199         __return_value_to_caller(item->req_id,
1200                         g_variant_new("(i)", PKGMGR_R_OK));
1201
1202         return 0;
1203 }
1204
1205 static int __process_decrypt_package(pm_dbus_msg *item)
1206 {
1207         int ret;
1208         char *drm_file_path;
1209         char *decrypted_file_path;
1210
1211         drm_file_path = item->pkgid;
1212         decrypted_file_path = item->args;
1213
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));
1221                 return -1;
1222         }
1223
1224         __return_value_to_caller(item->req_id,
1225                         g_variant_new("(i)", PKGMGR_R_OK));
1226
1227         return 0;
1228 }
1229
1230 static int __process_update_app_splash_screen(pm_dbus_msg *item, int flag)
1231 {
1232         int ret;
1233         bool is_global = false;
1234         const char *val;
1235
1236         ret = __change_item_info(item, item->uid, &is_global);
1237         if (ret != PMINFO_R_OK || strlen(item->appid) == 0)
1238                 return -1;
1239
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);
1244
1245         if (is_global)
1246                 ret = pkgmgr_parser_update_global_app_splash_screen_display_info_in_usr_db(
1247                                 item->appid, item->uid, flag);
1248         else
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,
1255                                 item->req_type);
1256         else
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,
1260                                 item->req_type);
1261
1262         return ret;
1263 }
1264
1265 static int __process_set_restriction_mode(pm_dbus_msg *item)
1266 {
1267         int ret;
1268         int mode;
1269
1270         mode = atoi(item->args);
1271         ret = _restriction_mode_set(item->uid, item->pkgid, mode);
1272
1273         __return_value_to_caller(item->req_id,
1274                         g_variant_new("(i)", ret));
1275
1276         return ret;
1277 }
1278
1279 static int __process_unset_restriction_mode(pm_dbus_msg *item)
1280 {
1281         int ret;
1282         int mode;
1283
1284         mode = atoi(item->args);
1285         ret = _restriction_mode_unset(item->uid, item->pkgid, mode);
1286
1287         __return_value_to_caller(item->req_id,
1288                         g_variant_new("(i)", ret));
1289
1290         return ret;
1291 }
1292
1293 static int __process_get_restriction_mode(pm_dbus_msg *item)
1294 {
1295         int ret;
1296         int mode = -1;
1297
1298         ret = _restriction_mode_get(item->uid, item->pkgid, &mode);
1299
1300         __return_value_to_caller(item->req_id,
1301                         g_variant_new("(ii)", mode, ret));
1302
1303         return ret;
1304 }
1305
1306 gboolean queue_job(void *data)
1307 {
1308         pm_dbus_msg *item = NULL;
1309         backend_info *ptr;
1310         int x;
1311         int ret;
1312
1313         /* Pop a job from queue */
1314         for (x = 0, ptr = begin; x < num_of_backends; x++, ptr++) {
1315                 if (__is_backend_busy(x))
1316                         continue;
1317
1318                 item = _pm_queue_pop(x);
1319                 if (item && item->req_type != -1)
1320                         break;
1321                 free(item);
1322         }
1323
1324         /* all backend messages queue are empty or busy */
1325         if (x == num_of_backends)
1326                 return FALSE;
1327
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);
1337
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);
1343                 if (ret != 0) {
1344                         ret = -1;
1345                         __send_fail_signal(ptr);
1346                         goto end;
1347                 }
1348         }
1349 #endif
1350
1351         switch (item->req_type) {
1352         case PKGMGR_REQUEST_TYPE_INSTALL:
1353                 __set_backend_busy(x);
1354                 ret = __process_install(item);
1355                 break;
1356         case PKGMGR_REQUEST_TYPE_MOUNT_INSTALL:
1357                 __set_backend_busy(x);
1358                 ret = __process_mount_install(item);
1359                 break;
1360         case PKGMGR_REQUEST_TYPE_REINSTALL:
1361                 __set_backend_busy(x);
1362                 ret = __process_reinstall(item);
1363                 break;
1364         case PKGMGR_REQUEST_TYPE_UNINSTALL:
1365                 __set_backend_busy(x);
1366                 ret = __process_uninstall(item);
1367                 break;
1368         case PKGMGR_REQUEST_TYPE_MOVE:
1369                 __set_backend_busy(x);
1370                 ret = __process_move(item);
1371                 break;
1372         case PKGMGR_REQUEST_TYPE_ENABLE_PKG:
1373                 __set_backend_busy(x);
1374                 ret = __process_enable_pkg(item);
1375                 break;
1376         case PKGMGR_REQUEST_TYPE_DISABLE_PKG:
1377                 __set_backend_busy(x);
1378                 ret = __process_disable_pkg(item);
1379                 break;
1380         case PKGMGR_REQUEST_TYPE_ENABLE_APP:
1381                 ret = __process_enable_app(item);
1382                 break;
1383         case PKGMGR_REQUEST_TYPE_DISABLE_APP:
1384                 ret = __process_disable_app(item);
1385                 break;
1386         case PKGMGR_REQUEST_TYPE_GETSIZE:
1387                 __set_backend_busy(x);
1388                 ret = __process_getsize(item);
1389                 break;
1390         case PKGMGR_REQUEST_TYPE_CLEARDATA:
1391                 __set_backend_busy(x);
1392                 ret = __process_cleardata(item);
1393                 break;
1394         case PKGMGR_REQUEST_TYPE_CLEARCACHE:
1395                 __set_backend_busy(x);
1396                 ret = __process_clearcache(item);
1397                 break;
1398         case PKGMGR_REQUEST_TYPE_ENABLE_GLOBAL_APP_FOR_UID:
1399                 ret = __process_enable_global_app_for_uid(item);
1400                 break;
1401         case PKGMGR_REQUEST_TYPE_DISABLE_GLOBAL_APP_FOR_UID:
1402                 ret = __process_disable_global_app_for_uid(item);
1403                 break;
1404         case PKGMGR_REQUEST_TYPE_KILL:
1405                 ret = __process_kill(item);
1406                 break;
1407         case PKGMGR_REQUEST_TYPE_CHECK:
1408                 ret = __process_check(item);
1409                 break;
1410         case PKGMGR_REQUEST_TYPE_GENERATE_LICENSE_REQUEST:
1411                 ret = __process_generate_license_request(item);
1412                 break;
1413         case PKGMGR_REQUEST_TYPE_REGISTER_LICENSE:
1414                 ret = __process_register_license(item);
1415                 break;
1416         case PKGMGR_REQUEST_TYPE_DECRYPT_PACKAGE:
1417                 ret = __process_decrypt_package(item);
1418                 break;
1419         case PKGMGR_REQUEST_TYPE_ENABLE_APP_SPLASH_SCREEN:
1420                 ret = __process_update_app_splash_screen(item, 1);
1421                 break;
1422         case PKGMGR_REQUEST_TYPE_DISABLE_APP_SPLASH_SCREEN:
1423                 ret = __process_update_app_splash_screen(item, 0);
1424                 break;
1425         case PKGMGR_REQUEST_TYPE_SET_RESTRICTION_MODE:
1426                 ret = __process_set_restriction_mode(item);
1427                 break;
1428         case PKGMGR_REQUEST_TYPE_UNSET_RESTRICTION_MODE:
1429                 ret = __process_unset_restriction_mode(item);
1430                 break;
1431         case PKGMGR_REQUEST_TYPE_GET_RESTRICTION_MODE:
1432                 ret = __process_get_restriction_mode(item);
1433                 break;
1434         default:
1435                 ret = -1;
1436                 break;
1437         }
1438
1439 #ifdef TIZEN_FEATURE_CSR
1440 end:
1441 #endif
1442         ptr->pid = ret;
1443         free(item);
1444
1445         return FALSE;
1446 }
1447
1448 #define IS_WHITESPACE(CHAR) \
1449 ((CHAR == ' ' || CHAR == '\t' || CHAR == '\r' || CHAR == '\n') ? TRUE : FALSE)
1450
1451 void _app_str_trim(char *input)
1452 {
1453         char *trim_str = input;
1454
1455         if (input == NULL)
1456                 return;
1457
1458         while (*input != 0) {
1459                 if (!IS_WHITESPACE(*input)) {
1460                         *trim_str = *input;
1461                         trim_str++;
1462                 }
1463                 input++;
1464         }
1465
1466         *trim_str = 0;
1467         return;
1468 }
1469
1470 char *_get_backend_cmd(char *type)
1471 {
1472         FILE *fp = NULL;
1473         char buffer[1024] = { 0 };
1474         char *command = NULL;
1475         int size = 0;
1476
1477         fp = fopen(PKG_CONF_PATH, "r");
1478         if (fp == NULL)
1479                 return NULL;
1480
1481         char *path = NULL;
1482         while (fgets(buffer, 1024, fp) != NULL) {
1483                 if (buffer[0] == '#')
1484                         continue;
1485
1486                 _app_str_trim(buffer);
1487
1488                 if ((path = strstr(buffer, PKG_BACKEND)) != NULL) {
1489                         DBG("buffer [%s]", buffer);
1490                         path = path + strlen(PKG_BACKEND);
1491                         DBG("path [%s]", path);
1492
1493                         command =
1494                             (char *)malloc(sizeof(char) * strlen(path) +
1495                                            strlen(type) + 1);
1496                         if (command == NULL) {
1497                                 fclose(fp);
1498                                 return NULL;
1499                         }
1500
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);
1505
1506                         if (fp != NULL)
1507                                 fclose(fp);
1508
1509                         return command;
1510                 }
1511
1512                 memset(buffer, 0x00, 1024);
1513         }
1514
1515         if (fp != NULL)
1516                 fclose(fp);
1517
1518         return NULL;            /* cannot find proper command */
1519 }
1520
1521 int main(int argc, char *argv[])
1522 {
1523         int r;
1524
1525         DBG("server start");
1526
1527         r = _pm_queue_init();
1528         if (r) {
1529                 DBG("Queue Initialization Failed\n");
1530                 return -1;
1531         }
1532
1533         r = __init_backend_info();
1534         if (r) {
1535                 DBG("backend info init failed");
1536                 return -1;
1537         }
1538
1539         r = __init_request_handler();
1540         if (r) {
1541                 ERR("dbus init failed");
1542                 return -1;
1543         }
1544
1545         if (__register_signal_handler()) {
1546                 ERR("failed to register signal handler");
1547                 return -1;
1548         }
1549
1550 #if !GLIB_CHECK_VERSION(2, 35, 0)
1551         g_type_init();
1552 #endif
1553         mainloop = g_main_loop_new(NULL, FALSE);
1554         if (!mainloop) {
1555                 ERR("g_main_loop_new failed");
1556                 return -1;
1557         }
1558
1559         DBG("Main loop is created.");
1560
1561         g_main_loop_run(mainloop);
1562
1563         DBG("Quit main loop.");
1564         __fini_request_handler();
1565         __fini_backend_info();
1566         _pm_queue_final();
1567
1568         DBG("package manager server terminated.");
1569
1570         return 0;
1571 }