Fix sending app signal
[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 <dirent.h>
33 #include <sys/types.h>
34 #include <fcntl.h>
35 #include <signal.h>
36 #include <grp.h>
37
38 #include <glib.h>
39 #include <gio/gio.h>
40
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 static int __pkgcmd_read_proc(const char *path, char *buf, int size)
295 {
296         int fd;
297         int ret;
298         if (buf == NULL || path == NULL)
299                 return -1;
300         fd = open(path, O_RDONLY);
301         if (fd < 0)
302                 return -1;
303         ret = read(fd, buf, size - 1);
304         if (ret <= 0) {
305                 close(fd);
306                 return -1;
307         } else
308                 buf[ret] = 0;
309         close(fd);
310         return ret;
311 }
312
313 static int __pkgcmd_find_pid_by_cmdline(const char *dname,
314                         const char *cmdline, const char *apppath)
315 {
316         int pid = 0;
317         int pgid = 0;
318
319         if (strcmp(cmdline, apppath) == 0) {
320                 pid = atoi(dname);
321                 pgid = getpgid(pid);
322                 if (pgid < 0) {
323                         ERR("getpgid failed, errno(%d)", errno);
324                         pid = 0;
325                 }
326                 if (pid != pgid)
327                         pid = 0;
328         }
329         return pid;
330 }
331
332 #ifdef TIZEN_FEATURE_CSR
333 static int __check_csr(backend_info *ptr)
334 {
335         csr_cs_context_h context = NULL;
336         csr_cs_malware_h detected = NULL;
337         int ret = -1;
338
339         ret = csr_cs_context_create(&context);
340         if (ret != CSR_ERROR_NONE) {
341                 ERR("Failed to create csr context");
342                 return -1;
343         }
344
345         if (context) {
346                 ret = csr_cs_scan_file(context, ptr->pkgid, &detected);
347                 DBG("CSR result[%d]", ret);
348
349                 csr_cs_context_destroy(context);
350                 if (detected != NULL) {
351                         ERR("CSR Denied[%s] Installation", ptr->pkgid);
352                         return -1;
353                 }
354         }
355
356         return 0;
357 }
358 #endif
359
360 static int __pkgcmd_proc_iter_kill_cmdline(const char *apppath, int option)
361 {
362         DIR *dp;
363         struct dirent dentry, *result;
364         int pid;
365         int ret;
366         char buf[1024] = {'\0'};
367         int pgid;
368
369         dp = opendir("/proc");
370         if (dp == NULL)
371                 return -1;
372
373         for (ret = readdir_r(dp, &dentry, &result);
374                         ret == 0 && result != NULL;
375                         ret = readdir_r(dp, &dentry, &result)) {
376                 if (!isdigit(dentry.d_name[0]))
377                         continue;
378
379                 snprintf(buf, sizeof(buf), "/proc/%s/cmdline", dentry.d_name);
380                 ret = __pkgcmd_read_proc(buf, buf, sizeof(buf));
381                 if (ret <= 0)
382                         continue;
383
384                 pid = __pkgcmd_find_pid_by_cmdline(dentry.d_name, buf, apppath);
385                 if (pid > 0) {
386                         if (option == 0) {
387                                 closedir(dp);
388                                 return pid;
389                         }
390                         pgid = getpgid(pid);
391                         if (pgid <= 1) {
392                                 closedir(dp);
393                                 ERR("getpgid failed, errno(%d)", errno);
394                                 return -1;
395                         }
396                         if (killpg(pgid, SIGKILL) < 0) {
397                                 closedir(dp);
398                                 ERR("killpg failed, errno(%d)", errno);
399                                 return -1;
400                         }
401                         closedir(dp);
402                         return pid;
403                 }
404         }
405         closedir(dp);
406         return 0;
407 }
408
409 static void __make_pid_info_file(char *req_key, int pid, uid_t uid)
410 {
411         FILE* file;
412         int fd;
413         int ret;
414         char buf[MAX_PKG_TYPE_LEN] = {0};
415         char info_file[PATH_MAX] = {'\0'};
416         struct passwd pwd;
417         struct passwd *pwd_result;
418
419         if (req_key == NULL)
420                 return;
421
422         ret = getpwuid_r(uid, &pwd, buf, sizeof(buf), &pwd_result);
423         if (ret != 0 || pwd_result == NULL) {
424                 ERR("get uid failed(%d) for user(%d)", ret, uid);
425                 return;
426         }
427         DBG("uid(%d), gid(%d)", uid, pwd.pw_gid);
428
429         snprintf(info_file, PATH_MAX, "/tmp/pkgmgr/%s", req_key);
430
431         DBG("info_path(%s)", info_file);
432         file = fopen(info_file, "w");
433         if (file == NULL) {
434                 ERR("Couldn't open the file(%s)", info_file);
435                 return;
436         }
437
438         snprintf(buf, MAX_PKG_TYPE_LEN, "%d\n", pid);
439         fwrite(buf, 1, strlen(buf), file);
440
441         fflush(file);
442         fd = fileno(file);
443         if (fchmod(fd, 0777) < 0)
444                 ERR("chmod failed, errno(%d)", errno);
445         if (fchown(fd, uid, pwd.pw_gid) < 0)
446                 ERR("chown failed, errno(%d)", errno);
447         fsync(fd);
448         fclose(file);
449 }
450
451 static int __kill_app(char *appid, uid_t uid)
452 {
453         pkgmgrinfo_appinfo_h appinfo;
454         int ret = PMINFO_R_ERROR;
455         char *exec = NULL;
456
457         ret = pkgmgrinfo_appinfo_get_usr_appinfo(appid, uid, &appinfo);
458         if (ret != PMINFO_R_OK)
459                 return PMINFO_R_ERROR;
460
461         ret = pkgmgrinfo_appinfo_get_exec(appinfo, &exec);
462         if (ret != PMINFO_R_OK) {
463                 pkgmgrinfo_appinfo_destroy_appinfo(appinfo);
464                 return PMINFO_R_ERROR;
465         }
466
467         ret = __pkgcmd_proc_iter_kill_cmdline(exec, 1);
468         if (ret != PMINFO_R_OK)
469                 DBG("failed to kill app[%s], exec[%s]", appid, exec);
470
471         pkgmgrinfo_appinfo_destroy_appinfo(appinfo);
472         return ret;
473 }
474
475 static int __pkgcmd_app_cb(const pkgmgrinfo_appinfo_h handle, void *user_data)
476 {
477         char *pkgid;
478         char *exec;
479         int ret;
480         int pid = -1;
481         pkgcmd_data *pdata = (pkgcmd_data *)user_data;
482
483         if (handle == NULL) {
484                 perror("appinfo handle is NULL\n");
485                 exit(1);
486         }
487         ret = pkgmgrinfo_appinfo_get_exec(handle, &exec);
488         if (ret) {
489                 perror("Failed to get app exec path\n");
490                 exit(1);
491         }
492         ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid);
493         if (ret) {
494                 perror("Failed to get pkgid\n");
495                 exit(1);
496         }
497
498         if (strcmp(pdata->cmd, "kill") == 0)
499                 pid = __pkgcmd_proc_iter_kill_cmdline(exec, 1);
500         else if (strcmp(pdata->cmd, "check") == 0)
501                 pid = __pkgcmd_proc_iter_kill_cmdline(exec, 0);
502
503         __make_pid_info_file(pkgid, pid, pdata->uid);
504
505         return 0;
506 }
507
508 void free_user_context(user_ctx* ctx)
509 {
510         char **env = NULL;
511         int i = 0;
512         if (!ctx)
513                 return;
514         env = ctx->env;
515         /* env variable ends by NULL element */
516         while (env[i]) {
517                 free(env[i]);
518                 i++;
519         }
520         free(env);
521         env = NULL;
522         free(ctx);
523 }
524
525 int set_environement(user_ctx *ctx)
526 {
527         int i = 0;
528         int res = 0;
529         char **env = NULL;
530         int n;
531         gid_t *groups;
532
533         if (!ctx)
534                 return -1;
535
536         n = getgroups(0, NULL);
537         if (n < 0) {
538                 ERR("Failed to get the number of supplementary group IDs");
539                 return -1;
540         }
541
542         groups = (gid_t *)calloc(1, sizeof(gid_t) * (n + 3));
543         if (groups == NULL) {
544                 ERR("out of memory");
545                 return -1;
546         }
547
548         n = getgroups(n, groups);
549         if (n < 0) {
550                 ERR("Failed to get list of supplementary group IDs");
551                 free(groups);
552                 return -1;
553         }
554
555         groups[n++] = EXT_STORAGE_GROUP;
556         groups[n++] = EXT_STORAGE_APPDATA_GROUP;
557         groups[n++] = MEDIA_STORAGE_GROUP;
558
559         if (setgroups(n, groups) < 0) {
560                 ERR("setgroups failed: %d", errno);
561                 free(groups);
562                 return -1;
563         }
564         free(groups);
565
566         env = ctx->env;
567         /* env variable ends by NULL element */
568         while (env[i]) {
569                 if (putenv(env[i]) != 0)
570                         res = -1;
571                 i++;
572         }
573         return res;
574 }
575
576 user_ctx *get_user_context(uid_t uid)
577 {
578         /* we can use getpwnam because this is used only after a
579          * fork and just before an execv
580          * No concurrencial call can corrupt the data
581          * returned by getpwuid
582          */
583         user_ctx *context_res;
584         char **env = NULL;
585         char buf[1024] = {0, };
586         struct passwd pwd, *result;
587         int len;
588         int ret = 0;
589         int i;
590
591         ret = getpwuid_r(uid, &pwd, buf, sizeof(buf), &result);
592         if (ret != 0 || result == NULL)
593                 return NULL;
594
595         do {
596                 context_res = (user_ctx *)malloc(sizeof(user_ctx));
597                 if (!context_res) {
598                         ret = -1;
599                         break;
600                 }
601                 env = (char **)malloc(3 * sizeof(char *));
602                 if (!env) {
603                         ret = -1;
604                         break;
605                 }
606                 /* Build environment context */
607                 len = snprintf(NULL, 0, "HOME=%s", pwd.pw_dir);
608                 env[0] = (char *)malloc((len + 1) * sizeof(char));
609                 if (env[0] == NULL) {
610                         ret = -1;
611                         break;
612                 }
613                 snprintf(env[0], len + 1, "HOME=%s", pwd.pw_dir);
614                 len = snprintf(NULL, 0, "USER=%s", pwd.pw_name);
615                 env[1] = (char *)malloc((len + 1) * sizeof(char));
616                 if (env[1] == NULL) {
617                         ret = -1;
618                         break;
619                 }
620                 snprintf(env[1], len + 1, "USER=%s", pwd.pw_name);
621                 env[2] = NULL;
622         } while (0);
623
624         if (ret == -1) {
625                 free(context_res);
626                 context_res = NULL;
627                 i = 0;
628                 /* env variable ends by NULL element */
629                 while (env && env[i]) {
630                         free(env[i]);
631                         i++;
632                 }
633                 free(env);
634                 env = NULL;
635         } else {
636                 context_res->env = env;
637                 context_res->uid = uid;
638                 context_res->gid = pwd.pw_gid;
639         }
640         return context_res;
641 }
642
643 static char **__generate_argv(const char *args)
644 {
645         /* Create args vector
646          * req_id + pkgid + args
647          *
648          * vector size = # of args +
649          *(req_id + pkgid + NULL termination = 3)
650          * Last value must be NULL for execv.
651          */
652         gboolean ret_parse;
653         gint argcp;
654         gchar **argvp;
655         GError *gerr = NULL;
656         int i;
657
658         ret_parse = g_shell_parse_argv(args, &argcp, &argvp, &gerr);
659         if (FALSE == ret_parse) {
660                 DBG("Failed to split args: %s", args);
661                 DBG("messsage: %s", gerr->message);
662                 exit(1);
663         }
664
665         /* dbg */
666         for (i = 0; i < argcp; i++)
667                 DBG(">>>>>> argsv[%d]=%s", i, argvp[i]);
668
669         return argvp;
670 }
671
672 void __set_environment(gpointer user_data)
673 {
674         user_ctx *ctx = (user_ctx *)user_data;
675
676         if (set_environement(ctx))
677                 DBG("Failed to set env for the user : %d", ctx->uid);
678 }
679
680 static int __fork_and_exec_with_args(char **argv, uid_t uid)
681 {
682         user_ctx* user_context;
683         GError *error = NULL;
684         gboolean ret;
685         int pid;
686
687         user_context = get_user_context(uid);
688         if (!user_context) {
689                 DBG("Failed to getenv");
690                 return -1;
691         }
692
693         ret = g_spawn_async(NULL, argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD,
694                         __set_environment, (gpointer)user_context, &pid,
695                         &error);
696         if (ret != TRUE) {
697                 ERR("Failed to excute backend: %s", error->message);
698                 g_error_free(error);
699         }
700
701         free_user_context(user_context);
702
703         return pid;
704 }
705
706 static int __change_item_info(pm_dbus_msg *item, uid_t uid, bool *is_global)
707 {
708         int ret = 0;
709         char *pkgid = NULL;
710         pkgmgrinfo_appinfo_h handle = NULL;
711
712         switch (item->req_type) {
713         case PKGMGR_REQUEST_TYPE_DISABLE_APP:
714         case PKGMGR_REQUEST_TYPE_DISABLE_GLOBAL_APP_FOR_UID:
715         case PKGMGR_REQUEST_TYPE_ENABLE_APP_SPLASH_SCREEN:
716         case PKGMGR_REQUEST_TYPE_DISABLE_APP_SPLASH_SCREEN:
717                 ret = pkgmgrinfo_appinfo_get_usr_appinfo(item->pkgid, uid, &handle);
718                 break;
719         case PKGMGR_REQUEST_TYPE_ENABLE_APP:
720         case PKGMGR_REQUEST_TYPE_ENABLE_GLOBAL_APP_FOR_UID:
721                 ret = pkgmgrinfo_appinfo_get_usr_disabled_appinfo(item->pkgid, uid, &handle);
722                 break;
723         default:
724                 return PMINFO_R_ERROR;
725         }
726
727         if (ret != PMINFO_R_OK)
728                 return PMINFO_R_ERROR;
729
730         ret = pkgmgrinfo_appinfo_is_global(handle, is_global);
731         if (ret != PMINFO_R_OK)
732                 goto catch;
733
734         if ((item->req_type == PKGMGR_REQUEST_TYPE_DISABLE_APP
735                         || item->req_type == PKGMGR_REQUEST_TYPE_ENABLE_APP)
736                         && *is_global) {
737                         ret = PMINFO_R_ERROR;
738                         goto catch;
739         } else if ((item->req_type == PKGMGR_REQUEST_TYPE_DISABLE_GLOBAL_APP_FOR_UID
740                         || item->req_type == PKGMGR_REQUEST_TYPE_ENABLE_GLOBAL_APP_FOR_UID)
741                         && !*is_global) {
742                         ret = PMINFO_R_ERROR;
743                         goto catch;
744         }
745
746         ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid);
747         if (ret != PMINFO_R_OK)
748                 goto catch;
749
750         strncpy(item->appid, item->pkgid, sizeof(item->pkgid) - 1);
751         memset((item->pkgid), 0, MAX_PKG_NAME_LEN);
752         strncpy(item->pkgid, pkgid, sizeof(item->pkgid) - 1);
753
754 catch:
755         pkgmgrinfo_appinfo_destroy_appinfo(handle);
756
757         return ret;
758 }
759
760 static int __process_install(pm_dbus_msg *item)
761 {
762         char *backend_cmd;
763         char **argv;
764         char args[MAX_PKG_ARGS_LEN] = {'\0', };
765         int pid;
766
767         backend_cmd = _get_backend_cmd(item->pkg_type);
768         if (backend_cmd == NULL)
769                 return -1;
770
771         snprintf(args, sizeof(args), "%s -k %s -i %s -u %d %s", backend_cmd,
772                         item->req_id, item->pkgid, (int)item->uid, item->args);
773
774         argv = __generate_argv(args);
775
776         pid = __fork_and_exec_with_args(argv, APPFW_UID);
777         g_strfreev(argv);
778         free(backend_cmd);
779
780         return pid;
781 }
782
783 static int __process_mount_install(pm_dbus_msg *item)
784 {
785         char *backend_cmd;
786         char **argv;
787         char args[MAX_PKG_ARGS_LEN] = {'\0', };
788         int pid;
789
790         backend_cmd = _get_backend_cmd(item->pkg_type);
791         if (backend_cmd == NULL)
792                 return -1;
793
794         snprintf(args, sizeof(args), "%s -k %s -w %s -u %d %s", backend_cmd,
795                                          item->req_id, item->pkgid, (int)item->uid, item->args);
796
797         argv = __generate_argv(args);
798
799         pid = __fork_and_exec_with_args(argv, APPFW_UID);
800         g_strfreev(argv);
801         free(backend_cmd);
802
803         return pid;
804 }
805
806 static int __process_reinstall(pm_dbus_msg *item)
807 {
808         char *backend_cmd;
809         char **argv;
810         char args[MAX_PKG_ARGS_LEN];
811         int pid;
812
813         backend_cmd = _get_backend_cmd(item->pkg_type);
814         if (backend_cmd == NULL)
815                 return -1;
816
817         snprintf(args, sizeof(args), "%s -k %s -r %s -u %d", backend_cmd,
818                         item->req_id, item->pkgid, (int)item->uid);
819         argv = __generate_argv(args);
820
821         pid = __fork_and_exec_with_args(argv, APPFW_UID);
822
823         g_strfreev(argv);
824         free(backend_cmd);
825
826         return pid;
827 }
828
829 static int __process_uninstall(pm_dbus_msg *item)
830 {
831         char *backend_cmd;
832         char **argv;
833         char args[MAX_PKG_ARGS_LEN];
834         int pid;
835
836         backend_cmd = _get_backend_cmd(item->pkg_type);
837         if (backend_cmd == NULL)
838                 return -1;
839
840         snprintf(args, sizeof(args), "%s -k %s -d %s -u %d", backend_cmd,
841                         item->req_id, item->pkgid, (int)item->uid);
842         argv = __generate_argv(args);
843
844         pid = __fork_and_exec_with_args(argv, APPFW_UID);
845
846         g_strfreev(argv);
847         free(backend_cmd);
848
849         return pid;
850 }
851
852 static int __process_move(pm_dbus_msg *item)
853 {
854         char *backend_cmd;
855         char **argv;
856         char args[MAX_PKG_ARGS_LEN];
857         int pid;
858
859         backend_cmd = _get_backend_cmd(item->pkg_type);
860         if (backend_cmd == NULL)
861                 return -1;
862
863         snprintf(args, sizeof(args), "%s -k %s -m %s -u %d -t %s", backend_cmd,
864                         item->req_id, item->pkgid, (int)item->uid, item->args);
865         argv = __generate_argv(args);
866
867         pid = __fork_and_exec_with_args(argv, APPFW_UID);
868
869         g_strfreev(argv);
870         free(backend_cmd);
871
872         return pid;
873 }
874
875 static int __process_enable_pkg(pm_dbus_msg *item)
876 {
877         char *backend_cmd;
878         char **argv;
879         char args[MAX_PKG_ARGS_LEN];
880         int pid;
881
882         backend_cmd = _get_backend_cmd(item->pkg_type);
883         if (backend_cmd == NULL)
884                 return -1;
885
886         snprintf(args, sizeof(args), "%s -k %s -u %d -A %s", backend_cmd,
887                         item->req_id, (int)item->uid, item->pkgid);
888         argv = __generate_argv(args);
889
890         pid = __fork_and_exec_with_args(argv, APPFW_UID);
891
892         g_strfreev(argv);
893         free(backend_cmd);
894
895         return pid;
896 }
897
898 static int __process_disable_pkg(pm_dbus_msg *item)
899 {
900         char *backend_cmd;
901         char **argv;
902         char args[MAX_PKG_ARGS_LEN];
903         int pid;
904
905         backend_cmd = _get_backend_cmd(item->pkg_type);
906         if (backend_cmd == NULL)
907                 return -1;
908
909         snprintf(args, sizeof(args), "%s -k %s -u %d -D %s", backend_cmd,
910                         item->req_id, (int)item->uid, item->pkgid);
911         argv = __generate_argv(args);
912
913         pid = __fork_and_exec_with_args(argv, APPFW_UID);
914
915         g_strfreev(argv);
916         free(backend_cmd);
917
918         return pid;
919 }
920
921 static int __process_enable_app(pm_dbus_msg *item)
922 {
923         int ret = -1;
924         bool is_global = false;
925
926         __send_app_signal(item->uid, item->req_id, item->pkgid, item->pkgid,
927                         PKGMGR_INSTALLER_START_KEY_STR,
928                         PKGMGR_INSTALLER_APP_ENABLE_EVENT_STR, item->req_type);
929
930         /* get actual pkgid and replace it to appid which is currently stored at pkgid variable */
931         ret = __change_item_info(item, item->uid, &is_global);
932         if (ret != PMINFO_R_OK || strlen(item->appid) == 0) {
933                 __send_app_signal(item->uid, item->req_id, item->pkgid, item->pkgid,
934                                 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_FAIL_EVENT_STR,
935                                 item->req_type);
936                 return ret;
937         }
938
939         ret = pkgmgr_parser_update_app_disable_info_in_usr_db(item->appid, item->uid, 0);
940         if (ret != PMINFO_R_OK)
941                 __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
942                                 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_FAIL_EVENT_STR,
943                                 item->req_type);
944         else
945                 __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
946                                 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_OK_EVENT_STR,
947                                 item->req_type);
948
949
950         return ret;
951 }
952
953 static int __process_disable_app(pm_dbus_msg *item)
954 {
955         int ret = -1;
956         bool is_global = false;
957
958         __send_app_signal(item->uid, item->req_id, item->pkgid, item->pkgid,
959                         PKGMGR_INSTALLER_START_KEY_STR,
960                         PKGMGR_INSTALLER_APP_DISABLE_EVENT_STR, item->req_type);
961
962         /* get actual pkgid and replace it to appid which is currently stored at pkgid variable */
963         ret = __change_item_info(item, item->uid, &is_global);
964         if (ret != PMINFO_R_OK || strlen(item->appid) == 0) {
965                 __send_app_signal(item->uid, item->req_id, item->pkgid, item->pkgid,
966                                 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_FAIL_EVENT_STR,
967                                 item->req_type);
968                 return ret;
969         }
970
971         ret = __kill_app(item->appid, item->uid);
972         if (ret != PMINFO_R_OK) {
973                 __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
974                                 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_FAIL_EVENT_STR,
975                                 item->req_type);
976         }
977
978         ret = pkgmgr_parser_update_app_disable_info_in_usr_db(item->appid, item->uid, 1);
979         if (ret != PMINFO_R_OK)
980                 __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
981                                 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_FAIL_EVENT_STR,
982                                 item->req_type);
983         else
984                 __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
985                                 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_OK_EVENT_STR,
986                                 item->req_type);
987
988         return ret;
989 }
990
991 static int __process_enable_global_app_for_uid(pm_dbus_msg *item)
992 {
993         int ret = -1;
994         bool is_global = true;
995
996         __send_app_signal(item->uid, item->req_id, item->pkgid, item->pkgid,
997                         PKGMGR_INSTALLER_START_KEY_STR,
998                         PKGMGR_INSTALLER_GLOBAL_APP_ENABLE_FOR_UID, item->req_type);
999
1000         /* get actual pkgid and replace it to appid which is currently stored at pkgid variable */
1001         ret = __change_item_info(item, item->uid, &is_global);
1002         if (ret != PMINFO_R_OK || strlen(item->appid) == 0) {
1003                 __send_app_signal(item->uid, item->req_id, item->pkgid, item->pkgid,
1004                                 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_FAIL_EVENT_STR,
1005                                 item->req_type);
1006                 return ret;
1007         }
1008
1009         ret = pkgmgr_parser_update_global_app_disable_for_uid_info_in_db(item->appid, item->uid, 0);
1010         if (ret != PMINFO_R_OK)
1011                 __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
1012                                 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_FAIL_EVENT_STR,
1013                                 item->req_type);
1014         else
1015                 __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
1016                                 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_OK_EVENT_STR,
1017                                 item->req_type);
1018
1019         return ret;
1020 }
1021
1022 static int __process_disable_global_app_for_uid(pm_dbus_msg *item)
1023 {
1024         int ret = -1;
1025         bool is_global = true;
1026
1027         __send_app_signal(item->uid, item->req_id,
1028                         item->pkgid, item->pkgid,
1029                         PKGMGR_INSTALLER_START_KEY_STR,
1030                         PKGMGR_INSTALLER_GLOBAL_APP_DISABLE_FOR_UID, item->req_type);
1031
1032         /* get actual pkgid and replace it to appid which is currently stored at pkgid variable */
1033         ret = __change_item_info(item, GLOBAL_USER, &is_global);
1034         if (ret != PMINFO_R_OK || strlen(item->appid) == 0) {
1035                 __send_app_signal(item->uid, item->req_id, item->pkgid, item->pkgid,
1036                                 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_FAIL_EVENT_STR,
1037                                 item->req_type);
1038                 return ret;
1039         }
1040
1041         ret = __kill_app(item->appid, item->uid);
1042         ret = pkgmgr_parser_update_global_app_disable_for_uid_info_in_db(item->appid,
1043                 item->uid, 1);
1044
1045         if (ret != PMINFO_R_OK)
1046                 __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
1047                                 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_FAIL_EVENT_STR,
1048                                 item->req_type);
1049         else
1050                 __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
1051                                 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_OK_EVENT_STR,
1052                                 item->req_type);
1053
1054         return ret;
1055 }
1056
1057 static int __process_getsize(pm_dbus_msg *item)
1058 {
1059         static const char *backend_cmd = "/usr/bin/pkg_getsize";
1060         char **argv;
1061         char args[MAX_PKG_ARGS_LEN];
1062         int pid;
1063
1064         snprintf(args, sizeof(args), "%s %s %s -k %s", backend_cmd, item->pkgid,
1065                         item->args, item->req_id);
1066         argv = __generate_argv(args);
1067         pid = __fork_and_exec_with_args(argv, item->uid);
1068
1069         g_strfreev(argv);
1070
1071         return pid;
1072 }
1073
1074 static int __process_cleardata(pm_dbus_msg *item)
1075 {
1076         char *backend_cmd;
1077         char **argv;
1078         char args[MAX_PKG_ARGS_LEN];
1079         int pid;
1080
1081         backend_cmd = _get_backend_cmd(item->pkg_type);
1082         if (backend_cmd == NULL)
1083                 return -1;
1084
1085         /* TODO: set movetype */
1086         snprintf(args, sizeof(args), "%s -k %s -c %s -u %d", backend_cmd,
1087                         item->req_id, item->pkgid, (int)item->uid);
1088         argv = __generate_argv(args);
1089
1090         pid = __fork_and_exec_with_args(argv, APPFW_UID);
1091
1092         g_strfreev(argv);
1093         free(backend_cmd);
1094
1095         return pid;
1096 }
1097
1098 static int __process_clearcache(pm_dbus_msg *item)
1099 {
1100         static const char *backend_cmd = "/usr/bin/pkg_clearcache";
1101         char **argv;
1102         char args[MAX_PKG_ARGS_LEN];
1103         int pid;
1104
1105         snprintf(args, sizeof(args), "%s %s", backend_cmd, item->pkgid);
1106         argv = __generate_argv(args);
1107         pid = __fork_and_exec_with_args(argv, item->uid);
1108
1109         g_strfreev(argv);
1110
1111         return pid;
1112 }
1113
1114 static int __process_kill(pm_dbus_msg *item)
1115 {
1116         int ret;
1117         pkgmgrinfo_pkginfo_h handle;
1118         pkgcmd_data *pdata = NULL;
1119
1120         ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(item->pkgid, item->uid,
1121                         &handle);
1122         if (ret < 0) {
1123                 ERR("Failed to get handle");
1124                 return -1;
1125         }
1126
1127         pdata = calloc(1, sizeof(pkgcmd_data));
1128         if (pdata == NULL) {
1129                 ERR("memory alloc failed");
1130                 return -1;
1131         }
1132         pdata->cmd = strdup("kill");
1133         if (pdata->cmd == NULL) {
1134                 ERR("out of memory");
1135                 free(pdata);
1136                 pdata = NULL;
1137                 return -1;
1138         }
1139         pdata->uid = item->uid;
1140         ret = pkgmgrinfo_appinfo_get_usr_list(handle, PMINFO_ALL_APP,
1141                         __pkgcmd_app_cb, pdata, item->uid);
1142         free(pdata->cmd);
1143         free(pdata);
1144         pdata = NULL;
1145         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1146         if (ret < 0) {
1147                 ERR("pkgmgrinfo_appinfo_get_list() failed");
1148                 return -1;
1149         }
1150
1151         return 0;
1152 }
1153
1154 static int __process_check(pm_dbus_msg *item)
1155 {
1156         int ret;
1157         pkgmgrinfo_pkginfo_h handle;
1158         pkgcmd_data *pdata = NULL;
1159
1160         ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(item->pkgid, item->uid,
1161                         &handle);
1162         if (ret < 0) {
1163                 ERR("Failed to get handle");
1164                 return -1;
1165         }
1166
1167         pdata = calloc(1, sizeof(pkgcmd_data));
1168         if (pdata == NULL) {
1169                 ERR("memory alloc failed");
1170                 return -1;
1171         }
1172         pdata->cmd = strdup("check");
1173         if (pdata->cmd == NULL) {
1174                 ERR("out of memory");
1175                 free(pdata);
1176                 pdata = NULL;
1177                 return -1;
1178         }
1179         pdata->uid = item->uid;
1180         ret = pkgmgrinfo_appinfo_get_usr_list(handle, PMINFO_ALL_APP,
1181                         __pkgcmd_app_cb, pdata, item->uid);
1182         free(pdata->cmd);
1183         free(pdata);
1184         pdata = NULL;
1185         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1186         if (ret < 0) {
1187                 ERR("pkgmgrinfo_appinfo_get_list() failed");
1188                 return -1;
1189         }
1190
1191         return 0;
1192 }
1193
1194 static int __process_generate_license_request(pm_dbus_msg *item)
1195 {
1196         int ret;
1197         char *resp_data;
1198         char req_data[MAX_PKG_ARGS_LEN];
1199         unsigned int req_data_len;
1200         char license_url[MAX_PKG_ARGS_LEN];
1201         unsigned int license_url_len;
1202
1203         resp_data = item->args;
1204         req_data_len = sizeof(req_data);
1205         license_url_len = sizeof(license_url);
1206
1207         ret = drm_tizen_generate_license_request(resp_data, strlen(resp_data),
1208                         req_data, &req_data_len, license_url, &license_url_len);
1209         if (ret != TADC_SUCCESS) {
1210                 ERR("drm_tizen_generate_license_request failed: %d", ret);
1211                 __return_value_to_caller(item->req_id, g_variant_new("(iss)",
1212                                         PKGMGR_R_ESYSTEM, "", ""));
1213                 return -1;
1214         }
1215
1216         __return_value_to_caller(item->req_id,
1217                         g_variant_new("(iss)", PKGMGR_R_OK, req_data,
1218                                 license_url));
1219
1220         return 0;
1221 }
1222
1223 static int __process_register_license(pm_dbus_msg *item)
1224 {
1225         int ret;
1226         char *resp_data;
1227
1228         resp_data = item->args;
1229
1230         ret = drm_tizen_register_license(resp_data, strlen(resp_data));
1231         if (ret != TADC_SUCCESS) {
1232                 ERR("drm_tizen_register_license failed: %d", ret);
1233                 __return_value_to_caller(item->req_id,
1234                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1235                 return -1;
1236         }
1237
1238         __return_value_to_caller(item->req_id,
1239                         g_variant_new("(i)", PKGMGR_R_OK));
1240
1241         return 0;
1242 }
1243
1244 static int __process_decrypt_package(pm_dbus_msg *item)
1245 {
1246         int ret;
1247         char *drm_file_path;
1248         char *decrypted_file_path;
1249
1250         drm_file_path = item->pkgid;
1251         decrypted_file_path = item->args;
1252
1253         /* TODO: check ownership of decrypted file */
1254         ret = drm_tizen_decrypt_package(drm_file_path, strlen(drm_file_path),
1255                         decrypted_file_path, strlen(decrypted_file_path));
1256         if (ret != TADC_SUCCESS) {
1257                 ERR("drm_tizen_register_license failed: %d", ret);
1258                 __return_value_to_caller(item->req_id,
1259                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1260                 return -1;
1261         }
1262
1263         __return_value_to_caller(item->req_id,
1264                         g_variant_new("(i)", PKGMGR_R_OK));
1265
1266         return 0;
1267 }
1268
1269 static int __process_update_app_splash_screen(pm_dbus_msg *item, int flag)
1270 {
1271         int ret;
1272         bool is_global = false;
1273         const char *val;
1274
1275         ret = __change_item_info(item, item->uid, &is_global);
1276         if (ret != PMINFO_R_OK || strlen(item->appid) == 0)
1277                 return -1;
1278
1279         val = flag ? PKGMGR_INSTALLER_APP_ENABLE_SPLASH_SCREEN_EVENT_STR :
1280                 PKGMGR_INSTALLER_APP_DISABLE_SPLASH_SCREEN_EVENT_STR;
1281         __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
1282                         PKGMGR_INSTALLER_START_KEY_STR, val, item->req_type);
1283
1284         if (is_global)
1285                 ret = pkgmgr_parser_update_global_app_splash_screen_display_info_in_usr_db(
1286                                 item->appid, item->uid, flag);
1287         else
1288                 ret = pkgmgr_parser_update_app_splash_screen_display_info_in_usr_db(
1289                         item->appid, item->uid, flag);
1290         if (ret != PMINFO_R_OK)
1291                 __send_app_signal(item->uid, item->req_id, item->pkgid,
1292                                 item->appid, PKGMGR_INSTALLER_END_KEY_STR,
1293                                 PKGMGR_INSTALLER_FAIL_EVENT_STR,
1294                                 item->req_type);
1295         else
1296                 __send_app_signal(item->uid, item->req_id, item->pkgid,
1297                                 item->appid, PKGMGR_INSTALLER_END_KEY_STR,
1298                                 PKGMGR_INSTALLER_OK_EVENT_STR,
1299                                 item->req_type);
1300
1301         return ret;
1302 }
1303
1304 static int __process_set_restriction_mode(pm_dbus_msg *item)
1305 {
1306         int ret;
1307         int mode;
1308
1309         mode = atoi(item->args);
1310         ret = _restriction_mode_set(item->uid, item->pkgid, mode);
1311
1312         __return_value_to_caller(item->req_id,
1313                         g_variant_new("(i)", ret));
1314
1315         return ret;
1316 }
1317
1318 static int __process_unset_restriction_mode(pm_dbus_msg *item)
1319 {
1320         int ret;
1321         int mode;
1322
1323         mode = atoi(item->args);
1324         ret = _restriction_mode_unset(item->uid, item->pkgid, mode);
1325
1326         __return_value_to_caller(item->req_id,
1327                         g_variant_new("(i)", ret));
1328
1329         return ret;
1330 }
1331
1332 static int __process_get_restriction_mode(pm_dbus_msg *item)
1333 {
1334         int ret;
1335         int mode = -1;
1336
1337         ret = _restriction_mode_get(item->uid, item->pkgid, &mode);
1338
1339         __return_value_to_caller(item->req_id,
1340                         g_variant_new("(ii)", mode, ret));
1341
1342         return ret;
1343 }
1344
1345 gboolean queue_job(void *data)
1346 {
1347         pm_dbus_msg *item = NULL;
1348         backend_info *ptr;
1349         int x;
1350         int ret;
1351
1352         /* Pop a job from queue */
1353         for (x = 0, ptr = begin; x < num_of_backends; x++, ptr++) {
1354                 if (__is_backend_busy(x))
1355                         continue;
1356
1357                 item = _pm_queue_pop(x);
1358                 if (item && item->req_type != -1)
1359                         break;
1360                 free(item);
1361         }
1362
1363         /* all backend messages queue are empty or busy */
1364         if (x == num_of_backends)
1365                 return FALSE;
1366
1367         /*save pkg type and pkg name for future*/
1368         strncpy(ptr->req_id, item->req_id, MAX_REQ_ID_LEN - 1);
1369         strncpy(ptr->pkgtype, item->pkg_type, MAX_PKG_TYPE_LEN - 1);
1370         strncpy(ptr->pkgid, item->pkgid, MAX_PKG_NAME_LEN - 1);
1371         strncpy(ptr->args, item->args, MAX_PKG_ARGS_LEN - 1);
1372         memset((item->appid), 0, MAX_PKG_NAME_LEN);
1373         ptr->uid = item->uid;
1374         ptr->req_type = item->req_type;
1375         DBG("handle request type [%d]", item->req_type);
1376
1377 #ifdef TIZEN_FEATURE_CSR
1378         if (item->req_type == PKGMGR_REQUEST_TYPE_INSTALL ||
1379                         item->req_type == PKGMGR_REQUEST_TYPE_MOUNT_INSTALL ||
1380                         item->req_type == PKGMGR_REQUEST_TYPE_REINSTALL) {
1381                 ret = __check_csr(ptr);
1382                 if (ret != 0) {
1383                         ret = -1;
1384                         __send_fail_signal(ptr);
1385                         goto end;
1386                 }
1387         }
1388 #endif
1389
1390         switch (item->req_type) {
1391         case PKGMGR_REQUEST_TYPE_INSTALL:
1392                 __set_backend_busy(x);
1393                 ret = __process_install(item);
1394                 break;
1395         case PKGMGR_REQUEST_TYPE_MOUNT_INSTALL:
1396                 __set_backend_busy(x);
1397                 ret = __process_mount_install(item);
1398                 break;
1399         case PKGMGR_REQUEST_TYPE_REINSTALL:
1400                 __set_backend_busy(x);
1401                 ret = __process_reinstall(item);
1402                 break;
1403         case PKGMGR_REQUEST_TYPE_UNINSTALL:
1404                 __set_backend_busy(x);
1405                 ret = __process_uninstall(item);
1406                 break;
1407         case PKGMGR_REQUEST_TYPE_MOVE:
1408                 __set_backend_busy(x);
1409                 ret = __process_move(item);
1410                 break;
1411         case PKGMGR_REQUEST_TYPE_ENABLE_PKG:
1412                 ret = __process_enable_pkg(item);
1413                 break;
1414         case PKGMGR_REQUEST_TYPE_DISABLE_PKG:
1415                 ret = __process_disable_pkg(item);
1416                 break;
1417         case PKGMGR_REQUEST_TYPE_ENABLE_APP:
1418                 ret = __process_enable_app(item);
1419                 break;
1420         case PKGMGR_REQUEST_TYPE_DISABLE_APP:
1421                 ret = __process_disable_app(item);
1422                 break;
1423         case PKGMGR_REQUEST_TYPE_GETSIZE:
1424                 __set_backend_busy(x);
1425                 ret = __process_getsize(item);
1426                 break;
1427         case PKGMGR_REQUEST_TYPE_CLEARDATA:
1428                 __set_backend_busy(x);
1429                 ret = __process_cleardata(item);
1430                 break;
1431         case PKGMGR_REQUEST_TYPE_CLEARCACHE:
1432                 __set_backend_busy(x);
1433                 ret = __process_clearcache(item);
1434                 break;
1435         case PKGMGR_REQUEST_TYPE_ENABLE_GLOBAL_APP_FOR_UID:
1436                 ret = __process_enable_global_app_for_uid(item);
1437                 break;
1438         case PKGMGR_REQUEST_TYPE_DISABLE_GLOBAL_APP_FOR_UID:
1439                 ret = __process_disable_global_app_for_uid(item);
1440                 break;
1441         case PKGMGR_REQUEST_TYPE_KILL:
1442                 ret = __process_kill(item);
1443                 break;
1444         case PKGMGR_REQUEST_TYPE_CHECK:
1445                 ret = __process_check(item);
1446                 break;
1447         case PKGMGR_REQUEST_TYPE_GENERATE_LICENSE_REQUEST:
1448                 ret = __process_generate_license_request(item);
1449                 break;
1450         case PKGMGR_REQUEST_TYPE_REGISTER_LICENSE:
1451                 ret = __process_register_license(item);
1452                 break;
1453         case PKGMGR_REQUEST_TYPE_DECRYPT_PACKAGE:
1454                 ret = __process_decrypt_package(item);
1455                 break;
1456         case PKGMGR_REQUEST_TYPE_ENABLE_APP_SPLASH_SCREEN:
1457                 ret = __process_update_app_splash_screen(item, 1);
1458                 break;
1459         case PKGMGR_REQUEST_TYPE_DISABLE_APP_SPLASH_SCREEN:
1460                 ret = __process_update_app_splash_screen(item, 0);
1461                 break;
1462         case PKGMGR_REQUEST_TYPE_SET_RESTRICTION_MODE:
1463                 ret = __process_set_restriction_mode(item);
1464                 break;
1465         case PKGMGR_REQUEST_TYPE_UNSET_RESTRICTION_MODE:
1466                 ret = __process_unset_restriction_mode(item);
1467                 break;
1468         case PKGMGR_REQUEST_TYPE_GET_RESTRICTION_MODE:
1469                 ret = __process_get_restriction_mode(item);
1470                 break;
1471         default:
1472                 ret = -1;
1473                 break;
1474         }
1475
1476 end:
1477         ptr->pid = ret;
1478         free(item);
1479
1480         return FALSE;
1481 }
1482
1483 #define IS_WHITESPACE(CHAR) \
1484 ((CHAR == ' ' || CHAR == '\t' || CHAR == '\r' || CHAR == '\n') ? TRUE : FALSE)
1485
1486 void _app_str_trim(char *input)
1487 {
1488         char *trim_str = input;
1489
1490         if (input == NULL)
1491                 return;
1492
1493         while (*input != 0) {
1494                 if (!IS_WHITESPACE(*input)) {
1495                         *trim_str = *input;
1496                         trim_str++;
1497                 }
1498                 input++;
1499         }
1500
1501         *trim_str = 0;
1502         return;
1503 }
1504
1505 char *_get_backend_cmd(char *type)
1506 {
1507         FILE *fp = NULL;
1508         char buffer[1024] = { 0 };
1509         char *command = NULL;
1510         int size = 0;
1511
1512         fp = fopen(PKG_CONF_PATH, "r");
1513         if (fp == NULL)
1514                 return NULL;
1515
1516         char *path = NULL;
1517         while (fgets(buffer, 1024, fp) != NULL) {
1518                 if (buffer[0] == '#')
1519                         continue;
1520
1521                 _app_str_trim(buffer);
1522
1523                 if ((path = strstr(buffer, PKG_BACKEND)) != NULL) {
1524                         DBG("buffer [%s]", buffer);
1525                         path = path + strlen(PKG_BACKEND);
1526                         DBG("path [%s]", path);
1527
1528                         command =
1529                             (char *)malloc(sizeof(char) * strlen(path) +
1530                                            strlen(type) + 1);
1531                         if (command == NULL) {
1532                                 fclose(fp);
1533                                 return NULL;
1534                         }
1535
1536                         size = strlen(path) + strlen(type) + 1;
1537                         snprintf(command, size, "%s%s", path, type);
1538                         command[strlen(path) + strlen(type)] = '\0';
1539                         DBG("command [%s]", command);
1540
1541                         if (fp != NULL)
1542                                 fclose(fp);
1543
1544                         return command;
1545                 }
1546
1547                 memset(buffer, 0x00, 1024);
1548         }
1549
1550         if (fp != NULL)
1551                 fclose(fp);
1552
1553         return NULL;            /* cannot find proper command */
1554 }
1555
1556 int main(int argc, char *argv[])
1557 {
1558         int r;
1559
1560         DBG("server start");
1561
1562         r = _pm_queue_init();
1563         if (r) {
1564                 DBG("Queue Initialization Failed\n");
1565                 return -1;
1566         }
1567
1568         r = __init_backend_info();
1569         if (r) {
1570                 DBG("backend info init failed");
1571                 return -1;
1572         }
1573
1574         r = __init_request_handler();
1575         if (r) {
1576                 ERR("dbus init failed");
1577                 return -1;
1578         }
1579
1580         if (__register_signal_handler()) {
1581                 ERR("failed to register signal handler");
1582                 return -1;
1583         }
1584
1585 #if !GLIB_CHECK_VERSION(2, 35, 0)
1586         g_type_init();
1587 #endif
1588         mainloop = g_main_loop_new(NULL, FALSE);
1589         if (!mainloop) {
1590                 ERR("g_main_loop_new failed");
1591                 return -1;
1592         }
1593
1594         DBG("Main loop is created.");
1595
1596         g_main_loop_run(mainloop);
1597
1598         DBG("Quit main loop.");
1599         __fini_request_handler();
1600         __fini_backend_info();
1601         _pm_queue_final();
1602
1603         DBG("package manager server terminated.");
1604
1605         return 0;
1606 }