suppess build warning on the profile which doesn't support CSR feature.
[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         /* get actual pkgid and replace it to appid which is currently stored at pkgid variable */
927         ret = __change_item_info(item, item->uid, &is_global);
928         if (ret != PMINFO_R_OK || strlen(item->appid) == 0) {
929                 __send_app_signal(item->uid, item->req_id, item->pkgid, item->pkgid,
930                                 PKGMGR_INSTALLER_START_KEY_STR,
931                                 PKGMGR_INSTALLER_APP_ENABLE_EVENT_STR, item->req_type);
932                 __send_app_signal(item->uid, item->req_id, item->pkgid, item->pkgid,
933                                 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_FAIL_EVENT_STR,
934                                 item->req_type);
935                 return ret;
936         }
937
938         __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
939                         PKGMGR_INSTALLER_START_KEY_STR,
940                         PKGMGR_INSTALLER_APP_ENABLE_EVENT_STR, item->req_type);
941
942         ret = pkgmgr_parser_update_app_disable_info_in_usr_db(item->appid, item->uid, 0);
943         if (ret != PMINFO_R_OK)
944                 __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
945                                 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_FAIL_EVENT_STR,
946                                 item->req_type);
947         else
948                 __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
949                                 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_OK_EVENT_STR,
950                                 item->req_type);
951
952
953         return ret;
954 }
955
956 static int __process_disable_app(pm_dbus_msg *item)
957 {
958         int ret = -1;
959         bool is_global = false;
960
961         /* get actual pkgid and replace it to appid which is currently stored at pkgid variable */
962         ret = __change_item_info(item, item->uid, &is_global);
963         if (ret != PMINFO_R_OK || strlen(item->appid) == 0) {
964                 __send_app_signal(item->uid, item->req_id, item->pkgid, item->pkgid,
965                                 PKGMGR_INSTALLER_START_KEY_STR,
966                                 PKGMGR_INSTALLER_APP_DISABLE_EVENT_STR, item->req_type);
967                 __send_app_signal(item->uid, item->req_id, item->pkgid, item->pkgid,
968                                 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_FAIL_EVENT_STR,
969                                 item->req_type);
970                 return ret;
971         }
972
973         __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
974                         PKGMGR_INSTALLER_START_KEY_STR,
975                         PKGMGR_INSTALLER_APP_DISABLE_EVENT_STR, item->req_type);
976
977         ret = __kill_app(item->appid, item->uid);
978         if (ret != PMINFO_R_OK) {
979                 __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
980                                 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_FAIL_EVENT_STR,
981                                 item->req_type);
982         }
983
984         ret = pkgmgr_parser_update_app_disable_info_in_usr_db(item->appid, item->uid, 1);
985         if (ret != PMINFO_R_OK)
986                 __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
987                                 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_FAIL_EVENT_STR,
988                                 item->req_type);
989         else
990                 __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
991                                 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_OK_EVENT_STR,
992                                 item->req_type);
993
994         return ret;
995 }
996
997 static int __process_enable_global_app_for_uid(pm_dbus_msg *item)
998 {
999         int ret = -1;
1000         bool is_global = true;
1001
1002         /* get actual pkgid and replace it to appid which is currently stored at pkgid variable */
1003         ret = __change_item_info(item, item->uid, &is_global);
1004         if (ret != PMINFO_R_OK || strlen(item->appid) == 0) {
1005                 __send_app_signal(item->uid, item->req_id, item->pkgid, item->pkgid,
1006                                 PKGMGR_INSTALLER_START_KEY_STR,
1007                                 PKGMGR_INSTALLER_GLOBAL_APP_ENABLE_FOR_UID, item->req_type);
1008                 __send_app_signal(item->uid, item->req_id, item->pkgid, item->pkgid,
1009                                 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_FAIL_EVENT_STR,
1010                                 item->req_type);
1011                 return ret;
1012         }
1013
1014         __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
1015                         PKGMGR_INSTALLER_START_KEY_STR,
1016                         PKGMGR_INSTALLER_GLOBAL_APP_ENABLE_FOR_UID, item->req_type);
1017
1018         ret = pkgmgr_parser_update_global_app_disable_for_uid_info_in_db(item->appid, item->uid, 0);
1019         if (ret != PMINFO_R_OK)
1020                 __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
1021                                 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_FAIL_EVENT_STR,
1022                                 item->req_type);
1023         else
1024                 __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
1025                                 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_OK_EVENT_STR,
1026                                 item->req_type);
1027
1028         return ret;
1029 }
1030
1031 static int __process_disable_global_app_for_uid(pm_dbus_msg *item)
1032 {
1033         int ret = -1;
1034         bool is_global = true;
1035
1036         /* get actual pkgid and replace it to appid which is currently stored at pkgid variable */
1037         ret = __change_item_info(item, GLOBAL_USER, &is_global);
1038         if (ret != PMINFO_R_OK || strlen(item->appid) == 0) {
1039                 __send_app_signal(item->uid, item->req_id,
1040                                 item->pkgid, item->pkgid,
1041                                 PKGMGR_INSTALLER_START_KEY_STR,
1042                                 PKGMGR_INSTALLER_GLOBAL_APP_DISABLE_FOR_UID, item->req_type);
1043                 __send_app_signal(item->uid, item->req_id, item->pkgid, item->pkgid,
1044                                 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_FAIL_EVENT_STR,
1045                                 item->req_type);
1046                 return ret;
1047         }
1048
1049         __send_app_signal(item->uid, item->req_id,
1050                         item->pkgid, item->appid,
1051                         PKGMGR_INSTALLER_START_KEY_STR,
1052                         PKGMGR_INSTALLER_GLOBAL_APP_DISABLE_FOR_UID, item->req_type);
1053
1054         ret = __kill_app(item->appid, item->uid);
1055         ret = pkgmgr_parser_update_global_app_disable_for_uid_info_in_db(item->appid,
1056                 item->uid, 1);
1057
1058         if (ret != PMINFO_R_OK)
1059                 __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
1060                                 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_FAIL_EVENT_STR,
1061                                 item->req_type);
1062         else
1063                 __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
1064                                 PKGMGR_INSTALLER_END_KEY_STR, PKGMGR_INSTALLER_OK_EVENT_STR,
1065                                 item->req_type);
1066
1067         return ret;
1068 }
1069
1070 static int __process_getsize(pm_dbus_msg *item)
1071 {
1072         static const char *backend_cmd = "/usr/bin/pkg_getsize";
1073         char **argv;
1074         char args[MAX_PKG_ARGS_LEN];
1075         int pid;
1076
1077         snprintf(args, sizeof(args), "%s %s %s -k %s", backend_cmd, item->pkgid,
1078                         item->args, item->req_id);
1079         argv = __generate_argv(args);
1080         pid = __fork_and_exec_with_args(argv, item->uid);
1081
1082         g_strfreev(argv);
1083
1084         return pid;
1085 }
1086
1087 static int __process_cleardata(pm_dbus_msg *item)
1088 {
1089         char *backend_cmd;
1090         char **argv;
1091         char args[MAX_PKG_ARGS_LEN];
1092         int pid;
1093
1094         backend_cmd = _get_backend_cmd(item->pkg_type);
1095         if (backend_cmd == NULL)
1096                 return -1;
1097
1098         /* TODO: set movetype */
1099         snprintf(args, sizeof(args), "%s -k %s -c %s -u %d", backend_cmd,
1100                         item->req_id, item->pkgid, (int)item->uid);
1101         argv = __generate_argv(args);
1102
1103         pid = __fork_and_exec_with_args(argv, APPFW_UID);
1104
1105         g_strfreev(argv);
1106         free(backend_cmd);
1107
1108         return pid;
1109 }
1110
1111 static int __process_clearcache(pm_dbus_msg *item)
1112 {
1113         static const char *backend_cmd = "/usr/bin/pkg_clearcache";
1114         char **argv;
1115         char args[MAX_PKG_ARGS_LEN];
1116         int pid;
1117
1118         snprintf(args, sizeof(args), "%s %s", backend_cmd, item->pkgid);
1119         argv = __generate_argv(args);
1120         pid = __fork_and_exec_with_args(argv, item->uid);
1121
1122         g_strfreev(argv);
1123
1124         return pid;
1125 }
1126
1127 static int __process_kill(pm_dbus_msg *item)
1128 {
1129         int ret;
1130         pkgmgrinfo_pkginfo_h handle;
1131         pkgcmd_data *pdata = NULL;
1132
1133         ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(item->pkgid, item->uid,
1134                         &handle);
1135         if (ret < 0) {
1136                 ERR("Failed to get handle");
1137                 return -1;
1138         }
1139
1140         pdata = calloc(1, sizeof(pkgcmd_data));
1141         if (pdata == NULL) {
1142                 ERR("memory alloc failed");
1143                 return -1;
1144         }
1145         pdata->cmd = strdup("kill");
1146         if (pdata->cmd == NULL) {
1147                 ERR("out of memory");
1148                 free(pdata);
1149                 pdata = NULL;
1150                 return -1;
1151         }
1152         pdata->uid = item->uid;
1153         ret = pkgmgrinfo_appinfo_get_usr_list(handle, PMINFO_ALL_APP,
1154                         __pkgcmd_app_cb, pdata, item->uid);
1155         free(pdata->cmd);
1156         free(pdata);
1157         pdata = NULL;
1158         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1159         if (ret < 0) {
1160                 ERR("pkgmgrinfo_appinfo_get_list() failed");
1161                 return -1;
1162         }
1163
1164         return 0;
1165 }
1166
1167 static int __process_check(pm_dbus_msg *item)
1168 {
1169         int ret;
1170         pkgmgrinfo_pkginfo_h handle;
1171         pkgcmd_data *pdata = NULL;
1172
1173         ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(item->pkgid, item->uid,
1174                         &handle);
1175         if (ret < 0) {
1176                 ERR("Failed to get handle");
1177                 return -1;
1178         }
1179
1180         pdata = calloc(1, sizeof(pkgcmd_data));
1181         if (pdata == NULL) {
1182                 ERR("memory alloc failed");
1183                 return -1;
1184         }
1185         pdata->cmd = strdup("check");
1186         if (pdata->cmd == NULL) {
1187                 ERR("out of memory");
1188                 free(pdata);
1189                 pdata = NULL;
1190                 return -1;
1191         }
1192         pdata->uid = item->uid;
1193         ret = pkgmgrinfo_appinfo_get_usr_list(handle, PMINFO_ALL_APP,
1194                         __pkgcmd_app_cb, pdata, item->uid);
1195         free(pdata->cmd);
1196         free(pdata);
1197         pdata = NULL;
1198         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1199         if (ret < 0) {
1200                 ERR("pkgmgrinfo_appinfo_get_list() failed");
1201                 return -1;
1202         }
1203
1204         return 0;
1205 }
1206
1207 static int __process_generate_license_request(pm_dbus_msg *item)
1208 {
1209         int ret;
1210         char *resp_data;
1211         char req_data[MAX_PKG_ARGS_LEN];
1212         unsigned int req_data_len;
1213         char license_url[MAX_PKG_ARGS_LEN];
1214         unsigned int license_url_len;
1215
1216         resp_data = item->args;
1217         req_data_len = sizeof(req_data);
1218         license_url_len = sizeof(license_url);
1219
1220         ret = drm_tizen_generate_license_request(resp_data, strlen(resp_data),
1221                         req_data, &req_data_len, license_url, &license_url_len);
1222         if (ret != TADC_SUCCESS) {
1223                 ERR("drm_tizen_generate_license_request failed: %d", ret);
1224                 __return_value_to_caller(item->req_id, g_variant_new("(iss)",
1225                                         PKGMGR_R_ESYSTEM, "", ""));
1226                 return -1;
1227         }
1228
1229         __return_value_to_caller(item->req_id,
1230                         g_variant_new("(iss)", PKGMGR_R_OK, req_data,
1231                                 license_url));
1232
1233         return 0;
1234 }
1235
1236 static int __process_register_license(pm_dbus_msg *item)
1237 {
1238         int ret;
1239         char *resp_data;
1240
1241         resp_data = item->args;
1242
1243         ret = drm_tizen_register_license(resp_data, strlen(resp_data));
1244         if (ret != TADC_SUCCESS) {
1245                 ERR("drm_tizen_register_license failed: %d", ret);
1246                 __return_value_to_caller(item->req_id,
1247                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1248                 return -1;
1249         }
1250
1251         __return_value_to_caller(item->req_id,
1252                         g_variant_new("(i)", PKGMGR_R_OK));
1253
1254         return 0;
1255 }
1256
1257 static int __process_decrypt_package(pm_dbus_msg *item)
1258 {
1259         int ret;
1260         char *drm_file_path;
1261         char *decrypted_file_path;
1262
1263         drm_file_path = item->pkgid;
1264         decrypted_file_path = item->args;
1265
1266         /* TODO: check ownership of decrypted file */
1267         ret = drm_tizen_decrypt_package(drm_file_path, strlen(drm_file_path),
1268                         decrypted_file_path, strlen(decrypted_file_path));
1269         if (ret != TADC_SUCCESS) {
1270                 ERR("drm_tizen_register_license failed: %d", ret);
1271                 __return_value_to_caller(item->req_id,
1272                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1273                 return -1;
1274         }
1275
1276         __return_value_to_caller(item->req_id,
1277                         g_variant_new("(i)", PKGMGR_R_OK));
1278
1279         return 0;
1280 }
1281
1282 static int __process_update_app_splash_screen(pm_dbus_msg *item, int flag)
1283 {
1284         int ret;
1285         bool is_global = false;
1286         const char *val;
1287
1288         ret = __change_item_info(item, item->uid, &is_global);
1289         if (ret != PMINFO_R_OK || strlen(item->appid) == 0)
1290                 return -1;
1291
1292         val = flag ? PKGMGR_INSTALLER_APP_ENABLE_SPLASH_SCREEN_EVENT_STR :
1293                 PKGMGR_INSTALLER_APP_DISABLE_SPLASH_SCREEN_EVENT_STR;
1294         __send_app_signal(item->uid, item->req_id, item->pkgid, item->appid,
1295                         PKGMGR_INSTALLER_START_KEY_STR, val, item->req_type);
1296
1297         if (is_global)
1298                 ret = pkgmgr_parser_update_global_app_splash_screen_display_info_in_usr_db(
1299                                 item->appid, item->uid, flag);
1300         else
1301                 ret = pkgmgr_parser_update_app_splash_screen_display_info_in_usr_db(
1302                         item->appid, item->uid, flag);
1303         if (ret != PMINFO_R_OK)
1304                 __send_app_signal(item->uid, item->req_id, item->pkgid,
1305                                 item->appid, PKGMGR_INSTALLER_END_KEY_STR,
1306                                 PKGMGR_INSTALLER_FAIL_EVENT_STR,
1307                                 item->req_type);
1308         else
1309                 __send_app_signal(item->uid, item->req_id, item->pkgid,
1310                                 item->appid, PKGMGR_INSTALLER_END_KEY_STR,
1311                                 PKGMGR_INSTALLER_OK_EVENT_STR,
1312                                 item->req_type);
1313
1314         return ret;
1315 }
1316
1317 static int __process_set_restriction_mode(pm_dbus_msg *item)
1318 {
1319         int ret;
1320         int mode;
1321
1322         mode = atoi(item->args);
1323         ret = _restriction_mode_set(item->uid, item->pkgid, mode);
1324
1325         __return_value_to_caller(item->req_id,
1326                         g_variant_new("(i)", ret));
1327
1328         return ret;
1329 }
1330
1331 static int __process_unset_restriction_mode(pm_dbus_msg *item)
1332 {
1333         int ret;
1334         int mode;
1335
1336         mode = atoi(item->args);
1337         ret = _restriction_mode_unset(item->uid, item->pkgid, mode);
1338
1339         __return_value_to_caller(item->req_id,
1340                         g_variant_new("(i)", ret));
1341
1342         return ret;
1343 }
1344
1345 static int __process_get_restriction_mode(pm_dbus_msg *item)
1346 {
1347         int ret;
1348         int mode = -1;
1349
1350         ret = _restriction_mode_get(item->uid, item->pkgid, &mode);
1351
1352         __return_value_to_caller(item->req_id,
1353                         g_variant_new("(ii)", mode, ret));
1354
1355         return ret;
1356 }
1357
1358 gboolean queue_job(void *data)
1359 {
1360         pm_dbus_msg *item = NULL;
1361         backend_info *ptr;
1362         int x;
1363         int ret;
1364
1365         /* Pop a job from queue */
1366         for (x = 0, ptr = begin; x < num_of_backends; x++, ptr++) {
1367                 if (__is_backend_busy(x))
1368                         continue;
1369
1370                 item = _pm_queue_pop(x);
1371                 if (item && item->req_type != -1)
1372                         break;
1373                 free(item);
1374         }
1375
1376         /* all backend messages queue are empty or busy */
1377         if (x == num_of_backends)
1378                 return FALSE;
1379
1380         /*save pkg type and pkg name for future*/
1381         strncpy(ptr->req_id, item->req_id, MAX_REQ_ID_LEN - 1);
1382         strncpy(ptr->pkgtype, item->pkg_type, MAX_PKG_TYPE_LEN - 1);
1383         strncpy(ptr->pkgid, item->pkgid, MAX_PKG_NAME_LEN - 1);
1384         strncpy(ptr->args, item->args, MAX_PKG_ARGS_LEN - 1);
1385         memset((item->appid), 0, MAX_PKG_NAME_LEN);
1386         ptr->uid = item->uid;
1387         ptr->req_type = item->req_type;
1388         DBG("handle request type [%d]", item->req_type);
1389
1390 #ifdef TIZEN_FEATURE_CSR
1391         if (item->req_type == PKGMGR_REQUEST_TYPE_INSTALL ||
1392                         item->req_type == PKGMGR_REQUEST_TYPE_MOUNT_INSTALL ||
1393                         item->req_type == PKGMGR_REQUEST_TYPE_REINSTALL) {
1394                 ret = __check_csr(ptr);
1395                 if (ret != 0) {
1396                         ret = -1;
1397                         __send_fail_signal(ptr);
1398                         goto end;
1399                 }
1400         }
1401 #endif
1402
1403         switch (item->req_type) {
1404         case PKGMGR_REQUEST_TYPE_INSTALL:
1405                 __set_backend_busy(x);
1406                 ret = __process_install(item);
1407                 break;
1408         case PKGMGR_REQUEST_TYPE_MOUNT_INSTALL:
1409                 __set_backend_busy(x);
1410                 ret = __process_mount_install(item);
1411                 break;
1412         case PKGMGR_REQUEST_TYPE_REINSTALL:
1413                 __set_backend_busy(x);
1414                 ret = __process_reinstall(item);
1415                 break;
1416         case PKGMGR_REQUEST_TYPE_UNINSTALL:
1417                 __set_backend_busy(x);
1418                 ret = __process_uninstall(item);
1419                 break;
1420         case PKGMGR_REQUEST_TYPE_MOVE:
1421                 __set_backend_busy(x);
1422                 ret = __process_move(item);
1423                 break;
1424         case PKGMGR_REQUEST_TYPE_ENABLE_PKG:
1425                 ret = __process_enable_pkg(item);
1426                 break;
1427         case PKGMGR_REQUEST_TYPE_DISABLE_PKG:
1428                 ret = __process_disable_pkg(item);
1429                 break;
1430         case PKGMGR_REQUEST_TYPE_ENABLE_APP:
1431                 ret = __process_enable_app(item);
1432                 break;
1433         case PKGMGR_REQUEST_TYPE_DISABLE_APP:
1434                 ret = __process_disable_app(item);
1435                 break;
1436         case PKGMGR_REQUEST_TYPE_GETSIZE:
1437                 __set_backend_busy(x);
1438                 ret = __process_getsize(item);
1439                 break;
1440         case PKGMGR_REQUEST_TYPE_CLEARDATA:
1441                 __set_backend_busy(x);
1442                 ret = __process_cleardata(item);
1443                 break;
1444         case PKGMGR_REQUEST_TYPE_CLEARCACHE:
1445                 __set_backend_busy(x);
1446                 ret = __process_clearcache(item);
1447                 break;
1448         case PKGMGR_REQUEST_TYPE_ENABLE_GLOBAL_APP_FOR_UID:
1449                 ret = __process_enable_global_app_for_uid(item);
1450                 break;
1451         case PKGMGR_REQUEST_TYPE_DISABLE_GLOBAL_APP_FOR_UID:
1452                 ret = __process_disable_global_app_for_uid(item);
1453                 break;
1454         case PKGMGR_REQUEST_TYPE_KILL:
1455                 ret = __process_kill(item);
1456                 break;
1457         case PKGMGR_REQUEST_TYPE_CHECK:
1458                 ret = __process_check(item);
1459                 break;
1460         case PKGMGR_REQUEST_TYPE_GENERATE_LICENSE_REQUEST:
1461                 ret = __process_generate_license_request(item);
1462                 break;
1463         case PKGMGR_REQUEST_TYPE_REGISTER_LICENSE:
1464                 ret = __process_register_license(item);
1465                 break;
1466         case PKGMGR_REQUEST_TYPE_DECRYPT_PACKAGE:
1467                 ret = __process_decrypt_package(item);
1468                 break;
1469         case PKGMGR_REQUEST_TYPE_ENABLE_APP_SPLASH_SCREEN:
1470                 ret = __process_update_app_splash_screen(item, 1);
1471                 break;
1472         case PKGMGR_REQUEST_TYPE_DISABLE_APP_SPLASH_SCREEN:
1473                 ret = __process_update_app_splash_screen(item, 0);
1474                 break;
1475         case PKGMGR_REQUEST_TYPE_SET_RESTRICTION_MODE:
1476                 ret = __process_set_restriction_mode(item);
1477                 break;
1478         case PKGMGR_REQUEST_TYPE_UNSET_RESTRICTION_MODE:
1479                 ret = __process_unset_restriction_mode(item);
1480                 break;
1481         case PKGMGR_REQUEST_TYPE_GET_RESTRICTION_MODE:
1482                 ret = __process_get_restriction_mode(item);
1483                 break;
1484         default:
1485                 ret = -1;
1486                 break;
1487         }
1488
1489 #ifdef TIZEN_FEATURE_CSR
1490 end:
1491 #endif
1492         ptr->pid = ret;
1493         free(item);
1494
1495         return FALSE;
1496 }
1497
1498 #define IS_WHITESPACE(CHAR) \
1499 ((CHAR == ' ' || CHAR == '\t' || CHAR == '\r' || CHAR == '\n') ? TRUE : FALSE)
1500
1501 void _app_str_trim(char *input)
1502 {
1503         char *trim_str = input;
1504
1505         if (input == NULL)
1506                 return;
1507
1508         while (*input != 0) {
1509                 if (!IS_WHITESPACE(*input)) {
1510                         *trim_str = *input;
1511                         trim_str++;
1512                 }
1513                 input++;
1514         }
1515
1516         *trim_str = 0;
1517         return;
1518 }
1519
1520 char *_get_backend_cmd(char *type)
1521 {
1522         FILE *fp = NULL;
1523         char buffer[1024] = { 0 };
1524         char *command = NULL;
1525         int size = 0;
1526
1527         fp = fopen(PKG_CONF_PATH, "r");
1528         if (fp == NULL)
1529                 return NULL;
1530
1531         char *path = NULL;
1532         while (fgets(buffer, 1024, fp) != NULL) {
1533                 if (buffer[0] == '#')
1534                         continue;
1535
1536                 _app_str_trim(buffer);
1537
1538                 if ((path = strstr(buffer, PKG_BACKEND)) != NULL) {
1539                         DBG("buffer [%s]", buffer);
1540                         path = path + strlen(PKG_BACKEND);
1541                         DBG("path [%s]", path);
1542
1543                         command =
1544                             (char *)malloc(sizeof(char) * strlen(path) +
1545                                            strlen(type) + 1);
1546                         if (command == NULL) {
1547                                 fclose(fp);
1548                                 return NULL;
1549                         }
1550
1551                         size = strlen(path) + strlen(type) + 1;
1552                         snprintf(command, size, "%s%s", path, type);
1553                         command[strlen(path) + strlen(type)] = '\0';
1554                         DBG("command [%s]", command);
1555
1556                         if (fp != NULL)
1557                                 fclose(fp);
1558
1559                         return command;
1560                 }
1561
1562                 memset(buffer, 0x00, 1024);
1563         }
1564
1565         if (fp != NULL)
1566                 fclose(fp);
1567
1568         return NULL;            /* cannot find proper command */
1569 }
1570
1571 int main(int argc, char *argv[])
1572 {
1573         int r;
1574
1575         DBG("server start");
1576
1577         r = _pm_queue_init();
1578         if (r) {
1579                 DBG("Queue Initialization Failed\n");
1580                 return -1;
1581         }
1582
1583         r = __init_backend_info();
1584         if (r) {
1585                 DBG("backend info init failed");
1586                 return -1;
1587         }
1588
1589         r = __init_request_handler();
1590         if (r) {
1591                 ERR("dbus init failed");
1592                 return -1;
1593         }
1594
1595         if (__register_signal_handler()) {
1596                 ERR("failed to register signal handler");
1597                 return -1;
1598         }
1599
1600 #if !GLIB_CHECK_VERSION(2, 35, 0)
1601         g_type_init();
1602 #endif
1603         mainloop = g_main_loop_new(NULL, FALSE);
1604         if (!mainloop) {
1605                 ERR("g_main_loop_new failed");
1606                 return -1;
1607         }
1608
1609         DBG("Main loop is created.");
1610
1611         g_main_loop_run(mainloop);
1612
1613         DBG("Quit main loop.");
1614         __fini_request_handler();
1615         __fini_backend_info();
1616         _pm_queue_final();
1617
1618         DBG("package manager server terminated.");
1619
1620         return 0;
1621 }