Add new implementation for pkg update info
[platform/core/appfw/pkgmgr-server.git] / src / pkgmgr-server.c
1 /*
2  * slp-pkgmgr
3  *
4  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
5  *
6  * Contact: Jayoun Lee <airjany@samsung.com>, Sewook Park <sewook7.park@samsung.com>,
7  * Jaeho Lee <jaeho81.lee@samsung.com>, Shobhit Srivastava <shobhit.s@samsung.com>
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  *
21  */
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 #include <ctype.h>
27 #include <unistd.h>
28 #include <pwd.h>
29 #include <sys/types.h>
30 #include <sys/wait.h>
31 #include <sys/stat.h>
32 #include <sys/types.h>
33 #include <sys/signalfd.h>
34 #include <signal.h>
35 #include <grp.h>
36 #include <fcntl.h>
37
38 #include <glib.h>
39 #include <gio/gio.h>
40
41 #include <aul.h>
42 #include <pkgmgr-info.h>
43 #include <pkgmgr/pkgmgr_parser_db.h>
44 #include <tzplatform_config.h>
45 #include <drm-tizen-apps.h>
46 #ifdef TIZEN_FEATURE_CSR
47 #include <csr-content-screening.h>
48 #endif
49
50 #include "pkgmgr_installer.h"
51 #include "pkgmgr-server.h"
52 #include "queue.h"
53 #include "package-manager.h"
54
55 #define OWNER_ROOT 0
56 #define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
57 #define APPFW_UID 301
58
59
60 #define EXT_STORAGE_GROUP 10001
61 #define EXT_STORAGE_APPDATA_GROUP 10002
62 #define MEDIA_STORAGE_GROUP 10502
63 #define ARRAY_SIZE(array) (sizeof(array) / sizeof(array[0]))
64 #define MAX_LONGLONG_LENGTH 32
65
66 typedef struct  {
67         char **env;
68         uid_t uid;
69         gid_t gid;
70 } user_ctx;
71
72 typedef struct {
73         uid_t uid;
74         char *cmd;
75         int pid;
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 static char backend_busy = 0;
84 extern int num_of_backends;
85 bool is_drm_busy = false;
86
87 static GIOChannel *sio;
88 static guint swid;
89 static GHashTable *backend_info_table;
90 static GMainLoop *mainloop;
91
92 static int __check_backend_status_for_exit(void);
93 static int __check_queue_status_for_exit(void);
94 static int __is_backend_busy(int position);
95 static void __set_backend_busy(int position);
96 static void __set_backend_free(int position);
97
98 gboolean exit_server(void *data);
99
100 /* To check whether a particular backend is free/busy */
101 static int __is_backend_busy(int position)
102 {
103         return backend_busy & (1 << position);
104 }
105 /* To set a particular backend as busy */
106 static void __set_backend_busy(int position)
107 {
108         backend_busy = backend_busy | (1 << position);
109 }
110 /* To set a particular backend as free */
111 static void __set_backend_free(int position)
112 {
113         backend_busy = backend_busy & ~(1 << position);
114 }
115
116 static gboolean getsize_io_handler(GIOChannel *io, GIOCondition cond,
117                 gpointer data)
118 {
119         GError *err = NULL;
120         GIOStatus s;
121         gsize len;
122         char buf[MAX_LONGLONG_LENGTH];
123         long long result = 0;
124         struct backend_job *job = (struct backend_job *)data;
125
126         s = g_io_channel_read_chars(io, (gchar *)buf, sizeof(buf), &len, &err);
127         if (s != G_IO_STATUS_NORMAL) {
128                 ERR("getsize fd read failed: %s", err->message);
129                 g_error_free(err);
130                 result = -1;
131         } else {
132                 if (strlen(buf) == 0) {
133                         ERR("empty result");
134                         result = -1;
135                 } else {
136                         result = atoll(buf);
137                 }
138         }
139
140         _return_value_to_caller(job->req_id, g_variant_new("(ix)",
141                 (result < 0) ? PKGMGR_R_ERROR : PKGMGR_R_OK, result));
142
143         unlink(job->extra->getsize_fifo);
144         free(job->extra->getsize_fifo);
145         job->extra->getsize_fifo = NULL;
146
147         return FALSE;
148 }
149
150 static int __setup_size_info_io(struct backend_job *job)
151 {
152         guint getsize_wid;
153
154         job->extra->getsize_fd = open(job->extra->getsize_fifo,
155                 O_RDONLY | O_NONBLOCK);
156         if (job->extra->getsize_fd < 0) {
157                 ERR("failed to open the fifo(%s), errno(%d)",
158                         job->extra->getsize_fifo, errno);
159                 return -1;
160         }
161
162         job->extra->getsize_io = g_io_channel_unix_new(job->extra->getsize_fd);
163         if (!job->extra->getsize_io)
164                 return -1;
165         g_io_channel_set_encoding(job->extra->getsize_io, NULL, NULL);
166         g_io_channel_set_buffered(job->extra->getsize_io, FALSE);
167         getsize_wid = g_io_add_watch(job->extra->getsize_io,
168                 G_IO_IN, getsize_io_handler, job);
169         if (!getsize_wid) {
170                 ERR("failed to add io watch");
171                 return -1;
172         }
173
174         return 0;
175 }
176
177 static gboolean __signal_handler(GIOChannel *io, GIOCondition cond,
178                 gpointer data)
179 {
180         GError *err = NULL;
181         GIOStatus s;
182         gsize len;
183         struct signalfd_siginfo fdsi;
184         struct backend_job *job;
185         pid_t pid;
186         int status;
187
188         s = g_io_channel_read_chars(io, (gchar *)&fdsi,
189                         sizeof(struct signalfd_siginfo), &len, &err);
190         if (s != G_IO_STATUS_NORMAL || len != sizeof(struct signalfd_siginfo)) {
191                 ERR("Signal read failed");
192                 g_error_free(err);
193                 return TRUE;
194         }
195
196         pid = waitpid(-1, &status, WNOHANG);
197         job = (struct backend_job *)g_hash_table_lookup(backend_info_table,
198                         (gconstpointer)pid);
199         if (job == NULL) {
200                 ERR("Unknown child exit");
201                 return -1;
202         }
203
204         __set_backend_free(job->backend_slot);
205         if (WIFSIGNALED(status)) {
206                 _send_fail_signal(job);
207                 INFO("backend[%s][%d] exit with signal[%d]", job->backend_type,
208                                 pid, WTERMSIG(status));
209         } else if (WEXITSTATUS(status)) {
210                 INFO("backend[%s][%d] exit with error", job->backend_type, pid);
211         } else {
212                 INFO("backend[%s][%d] exit", job->backend_type, pid);
213         }
214
215         if (job->extra) {
216                 if (job->extra->getsize_fifo) {
217                         ERR("invalid backend close");
218                         _return_value_to_caller(job->req_id,
219                                 g_variant_new("(ix)", PKGMGR_R_ERROR, -1));
220                 }
221         }
222
223         g_hash_table_remove(backend_info_table, (gconstpointer)pid);
224         g_idle_add(queue_job, NULL);
225
226         return TRUE;
227 }
228
229 static int __init_backend_info(void)
230 {
231         backend_info_table = g_hash_table_new_full(g_direct_hash,
232                         g_direct_equal, NULL,
233                         (GDestroyNotify)_free_backend_job);
234
235         return 0;
236 }
237
238 static void __fini_backend_info(void)
239 {
240         /*Free backend info */
241         g_hash_table_destroy(backend_info_table);
242 }
243
244 static int __register_signal_handler(void)
245 {
246         sigset_t mask;
247         int sfd;
248
249         sigemptyset(&mask);
250         sigaddset(&mask, SIGCHLD);
251
252         if (sigprocmask(SIG_BLOCK, &mask, NULL) == -1) {
253                 ERR("sigprocmask failed");
254                 return -1;
255         }
256
257         sfd = signalfd(-1, &mask, SFD_NONBLOCK);
258         if (sfd == -1) {
259                 ERR("signalfd failed");
260                 return -1;
261         }
262
263         sio = g_io_channel_unix_new(sfd);
264         g_io_channel_set_close_on_unref(sio, TRUE);
265         g_io_channel_set_encoding(sio, NULL, NULL);
266         g_io_channel_set_buffered(sio, FALSE);
267         swid = g_io_add_watch(sio, G_IO_IN, __signal_handler, NULL);
268
269         g_timeout_add_seconds_full(G_PRIORITY_LOW, 2, exit_server, NULL, NULL);
270
271         return 0;
272 }
273
274 static int __check_backend_status_for_exit(void)
275 {
276         int i;
277         for (i = 0; i < num_of_backends; i++) {
278                 if (__is_backend_busy(i))
279                         return 0;
280         }
281         return 1;
282 }
283
284 static int __check_queue_status_for_exit(void)
285 {
286         int i;
287         for (i = 0; i < num_of_backends; i++) {
288                 if (_is_queue_empty(i) == 0)
289                         return 0;
290         }
291         return 1;
292 }
293
294 gboolean exit_server(void *data)
295 {
296         DBG("exit_server Start");
297         if (__check_backend_status_for_exit() &&
298                         __check_queue_status_for_exit() && !is_drm_busy) {
299                 g_main_loop_quit(mainloop);
300                 return FALSE;
301         }
302         return TRUE;
303 }
304
305 #ifdef TIZEN_FEATURE_CSR
306 static int __check_csr(const char *path)
307 {
308         csr_cs_context_h context = NULL;
309         csr_cs_malware_h detected = NULL;
310         int ret = -1;
311
312         ret = csr_cs_context_create(&context);
313         if (ret != CSR_ERROR_NONE) {
314                 ERR("Failed to create csr context");
315                 return -1;
316         }
317
318         if (context) {
319                 ret = csr_cs_scan_file(context, path, &detected);
320                 DBG("CSR result[%d]", ret);
321
322                 csr_cs_context_destroy(context);
323                 if (detected != NULL) {
324                         ERR("CSR Denied[%s] Installation", path);
325                         return -1;
326                 }
327         }
328
329         return 0;
330 }
331 #endif
332
333 static int __kill_app(char *appid, uid_t uid)
334 {
335         int ret;
336         int pid;
337         int is_running;
338
339         is_running = aul_app_is_running_for_uid(appid, uid);
340         /* app is not running */
341         if (!is_running)
342                 return 0;
343
344         pid = aul_app_get_pid_for_uid(appid, uid);
345         if (pid == -1)
346                 return -1;
347
348         ret = aul_terminate_pid_for_uid(pid, uid);
349         if (ret != AUL_R_OK) {
350                 ERR("failed to terminate app(%d)", appid);
351                 return -1;
352         }
353
354         return 0;
355 }
356
357 static int __check_app(char *appid, uid_t uid)
358 {
359         int pid;
360         int is_running;
361
362         is_running = aul_app_is_running_for_uid(appid, uid);
363         if (!is_running)
364                 return 0;
365
366         pid = aul_app_get_pid_for_uid(appid, uid);
367
368         return pid;
369 }
370
371 static int __pkgcmd_app_cb(const pkgmgrinfo_appinfo_h handle, void *user_data)
372 {
373         char *pkgid;
374         char *appid;
375         char *exec;
376         int ret;
377         pkgcmd_data *pdata = (pkgcmd_data *)user_data;
378
379         if (handle == NULL) {
380                 perror("appinfo handle is NULL\n");
381                 exit(1);
382         }
383         ret = pkgmgrinfo_appinfo_get_exec(handle, &exec);
384         if (ret) {
385                 perror("Failed to get app exec path\n");
386                 exit(1);
387         }
388         ret = pkgmgrinfo_appinfo_get_appid(handle, &appid);
389         if (ret) {
390                 perror("Failed to get appid\n");
391                 exit(1);
392         }
393         ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid);
394         if (ret) {
395                 perror("Failed to get pkgid\n");
396                 exit(1);
397         }
398
399         if (strcmp(pdata->cmd, "kill") == 0) {
400                 pdata->pid = __check_app(appid, pdata->uid);
401                 if (pdata->pid > 0)
402                         ret = __kill_app(appid, pdata->uid);
403         } else if (strcmp(pdata->cmd, "check") == 0) {
404                 pdata->pid = __check_app(appid, pdata->uid);
405         }
406
407         return 0;
408 }
409
410 void free_user_context(user_ctx *ctx)
411 {
412         char **env = NULL;
413         int i = 0;
414         if (!ctx)
415                 return;
416         env = ctx->env;
417         /* env variable ends by NULL element */
418         while (env[i]) {
419                 free(env[i]);
420                 i++;
421         }
422         free(env);
423         env = NULL;
424         free(ctx);
425 }
426
427 int set_environement(user_ctx *ctx)
428 {
429         int i = 0;
430         int res = 0;
431         char **env = NULL;
432         int n;
433         gid_t *groups;
434
435         if (!ctx)
436                 return -1;
437
438         if (ctx->uid != APPFW_UID) {
439                 if (setuid(ctx->uid)) {
440                         ERR("setuid failed: %d", errno);
441                         return -1;
442                 }
443
444                 if (setgid(ctx->gid)) {
445                         ERR("setgid failed: %d", errno);
446                         return -1;
447                 }
448         }
449
450         n = getgroups(0, NULL);
451         if (n < 0) {
452                 ERR("Failed to get the number of supplementary group IDs");
453                 return -1;
454         }
455
456         groups = (gid_t *)calloc(1, sizeof(gid_t) * (n + 3));
457         if (groups == NULL) {
458                 ERR("out of memory");
459                 return -1;
460         }
461
462         n = getgroups(n, groups);
463         if (n < 0) {
464                 ERR("Failed to get list of supplementary group IDs");
465                 free(groups);
466                 return -1;
467         }
468
469         groups[n++] = EXT_STORAGE_GROUP;
470         groups[n++] = EXT_STORAGE_APPDATA_GROUP;
471         groups[n++] = MEDIA_STORAGE_GROUP;
472
473         if (setgroups(n, groups) < 0) {
474                 ERR("setgroups failed: %d", errno);
475                 free(groups);
476                 return -1;
477         }
478         free(groups);
479
480         env = ctx->env;
481         /* env variable ends by NULL element */
482         while (env[i]) {
483                 if (putenv(env[i]) != 0)
484                         res = -1;
485                 i++;
486         }
487         return res;
488 }
489
490 user_ctx *get_user_context(uid_t uid)
491 {
492         /* we can use getpwnam because this is used only after a
493          * fork and just before an execv
494          * No concurrencial call can corrupt the data
495          * returned by getpwuid
496          */
497         user_ctx *context_res;
498         char **env = NULL;
499         char buf[1024] = {0, };
500         struct passwd pwd, *result;
501         int len;
502         int ret = 0;
503         int i;
504
505         ret = getpwuid_r(uid, &pwd, buf, sizeof(buf), &result);
506         if (ret != 0 || result == NULL)
507                 return NULL;
508
509         do {
510                 context_res = (user_ctx *)malloc(sizeof(user_ctx));
511                 if (!context_res) {
512                         ret = -1;
513                         break;
514                 }
515                 env = (char **)malloc(3 * sizeof(char *));
516                 if (!env) {
517                         ret = -1;
518                         break;
519                 }
520                 /* Build environment context */
521                 len = snprintf(NULL, 0, "HOME=%s", pwd.pw_dir);
522                 env[0] = (char *)malloc((len + 1) * sizeof(char));
523                 if (env[0] == NULL) {
524                         ret = -1;
525                         break;
526                 }
527                 snprintf(env[0], len + 1, "HOME=%s", pwd.pw_dir);
528                 len = snprintf(NULL, 0, "USER=%s", pwd.pw_name);
529                 env[1] = (char *)malloc((len + 1) * sizeof(char));
530                 if (env[1] == NULL) {
531                         ret = -1;
532                         break;
533                 }
534                 snprintf(env[1], len + 1, "USER=%s", pwd.pw_name);
535                 env[2] = NULL;
536         } while (0);
537
538         if (ret == -1) {
539                 free(context_res);
540                 context_res = NULL;
541                 i = 0;
542                 /* env variable ends by NULL element */
543                 while (env && env[i]) {
544                         free(env[i]);
545                         i++;
546                 }
547                 free(env);
548                 env = NULL;
549         } else {
550                 context_res->env = env;
551                 context_res->uid = uid;
552                 context_res->gid = pwd.pw_gid;
553         }
554         return context_res;
555 }
556
557 static char **__generate_argv(const char *args)
558 {
559         /* Create args vector
560          * req_id + pkgid + args
561          *
562          * vector size = # of args +
563          *(req_id + pkgid + NULL termination = 3)
564          * Last value must be NULL for execv.
565          */
566         gboolean ret_parse;
567         gint argcp;
568         gchar **argvp;
569         GError *gerr = NULL;
570         int i;
571
572         ret_parse = g_shell_parse_argv(args, &argcp, &argvp, &gerr);
573         if (FALSE == ret_parse) {
574                 ERR("Failed to split args: %s", args);
575                 ERR("messsage: %s", gerr->message);
576                 exit(1);
577         }
578
579         /* dbg */
580         for (i = 0; i < argcp; i++)
581                 DBG(">>>>>> argsv[%d]=%s", i, argvp[i]);
582
583         return argvp;
584 }
585
586 void __set_environment(gpointer user_data)
587 {
588         user_ctx *ctx = (user_ctx *)user_data;
589
590         if (set_environement(ctx))
591                 ERR("Failed to set env for the user : %d", ctx->uid);
592 }
593
594 static int __fork_and_exec_with_args(char **argv, uid_t uid)
595 {
596         user_ctx *user_context;
597         GError *error = NULL;
598         gboolean ret;
599         int pid;
600
601         user_context = get_user_context(uid);
602         if (!user_context) {
603                 ERR("Failed to getenv");
604                 return -1;
605         }
606
607         ret = g_spawn_async(NULL, argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD,
608                         __set_environment, (gpointer)user_context, &pid,
609                         &error);
610         if (ret != TRUE) {
611                 ERR("Failed to excute backend: %s", error->message);
612                 g_error_free(error);
613                 free_user_context(user_context);
614                 return -1;
615         }
616
617         free_user_context(user_context);
618
619         return pid;
620 }
621
622 static int __change_job_info(struct backend_job *job, uid_t uid,
623                 bool *is_global)
624 {
625         int ret = 0;
626         char *pkgid = NULL;
627         pkgmgrinfo_appinfo_h handle = NULL;
628         if (job->req_type != REQUEST_TYPE_DISABLE_APP &&
629                         job->req_type != REQUEST_TYPE_DISABLE_GLOBAL_APP_FOR_UID &&
630                         job->req_type != REQUEST_TYPE_ENABLE_APP_SPLASH_SCREEN &&
631                         job->req_type != REQUEST_TYPE_DISABLE_APP_SPLASH_SCREEN &&
632                         job->req_type != REQUEST_TYPE_ENABLE_APP &&
633                         job->req_type != REQUEST_TYPE_ENABLE_GLOBAL_APP_FOR_UID)
634                 return PMINFO_R_ERROR;
635
636         ret = pkgmgrinfo_appinfo_get_usr_all_appinfo(job->pkgid, uid, &handle);
637         if (ret != PMINFO_R_OK)
638                 return PMINFO_R_ERROR;
639
640         ret = pkgmgrinfo_appinfo_is_global(handle, is_global);
641         if (ret != PMINFO_R_OK)
642                 goto catch;
643
644         if ((job->req_type == REQUEST_TYPE_DISABLE_GLOBAL_APP_FOR_UID ||
645                         job->req_type ==
646                         REQUEST_TYPE_ENABLE_GLOBAL_APP_FOR_UID) &&
647                         !*is_global) {
648                 ret = PMINFO_R_ERROR;
649                 goto catch;
650         }
651
652         ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid);
653         if (ret != PMINFO_R_OK)
654                 goto catch;
655
656         free(job->appid);
657         job->appid = strdup(job->pkgid);
658         free(job->pkgid);
659         job->pkgid = strdup(pkgid);
660
661 catch:
662         pkgmgrinfo_appinfo_destroy_appinfo(handle);
663
664         return ret;
665 }
666
667 static int __process_install(struct backend_job *job)
668 {
669         char *backend_cmd;
670         char **argv;
671         char args[MAX_PKG_ARGS_LEN];
672         gchar *req_id;
673         gchar *pkgid;
674         int pid;
675
676         backend_cmd = job->backend_path;
677         if (backend_cmd == NULL)
678                 return -1;
679
680         req_id = g_shell_quote(job->req_id);
681         pkgid = g_shell_quote(job->pkgid);
682         if (!req_id || !pkgid)
683                 return -1;
684
685         snprintf(args, sizeof(args), "%s -k %s -i %s -u %d %s", backend_cmd,
686                         req_id, pkgid, (int)job->target_uid, job->args);
687
688         argv = __generate_argv(args);
689
690         pid = __fork_and_exec_with_args(argv, APPFW_UID);
691         g_strfreev(argv);
692         g_free(req_id);
693         g_free(pkgid);
694
695         return pid;
696 }
697
698 static int __process_mount_install(struct backend_job *job)
699 {
700         char *backend_cmd;
701         char **argv;
702         char args[MAX_PKG_ARGS_LEN];
703         gchar *req_id;
704         gchar *pkgid;
705         int pid;
706
707         backend_cmd = job->backend_path;
708         if (backend_cmd == NULL)
709                 return -1;
710
711         req_id = g_shell_quote(job->req_id);
712         pkgid = g_shell_quote(job->pkgid);
713         if (!req_id || !pkgid)
714                 return -1;
715
716         snprintf(args, sizeof(args), "%s -k %s -w %s -u %d %s", backend_cmd,
717                         req_id, pkgid, (int)job->target_uid, job->args);
718
719         argv = __generate_argv(args);
720
721         pid = __fork_and_exec_with_args(argv, APPFW_UID);
722         g_strfreev(argv);
723         g_free(req_id);
724         g_free(pkgid);
725
726         return pid;
727 }
728
729 static int __process_reinstall(struct backend_job *job)
730 {
731         char *backend_cmd;
732         char **argv;
733         char args[MAX_PKG_ARGS_LEN];
734         gchar *req_id;
735         gchar *pkgid;
736         int pid;
737
738         backend_cmd = job->backend_path;
739         if (backend_cmd == NULL)
740                 return -1;
741
742         req_id = g_shell_quote(job->req_id);
743         pkgid = g_shell_quote(job->pkgid);
744         if (!req_id || !pkgid)
745                 return -1;
746
747         snprintf(args, sizeof(args), "%s -k %s -r %s -u %d", backend_cmd,
748                         req_id, pkgid, (int)job->target_uid);
749         argv = __generate_argv(args);
750
751         pid = __fork_and_exec_with_args(argv, APPFW_UID);
752
753         g_strfreev(argv);
754         g_free(req_id);
755         g_free(pkgid);
756
757         return pid;
758 }
759
760 static int __process_uninstall(struct backend_job *job)
761 {
762         char *backend_cmd;
763         char **argv;
764         char args[MAX_PKG_ARGS_LEN];
765         int pid;
766
767         backend_cmd = job->backend_path;
768         if (backend_cmd == NULL)
769                 return -1;
770
771         snprintf(args, sizeof(args), "%s -k %s -d %s -u %d", backend_cmd,
772                         job->req_id, job->pkgid, (int)job->target_uid);
773         argv = __generate_argv(args);
774
775         pid = __fork_and_exec_with_args(argv, APPFW_UID);
776
777         g_strfreev(argv);
778
779         return pid;
780 }
781
782 static int __process_move(struct backend_job *job)
783 {
784         char *backend_cmd;
785         char **argv;
786         char args[MAX_PKG_ARGS_LEN];
787         int pid;
788
789         backend_cmd = job->backend_path;
790         if (backend_cmd == NULL)
791                 return -1;
792
793         snprintf(args, sizeof(args), "%s -k %s -m %s -u %d -t %s", backend_cmd,
794                         job->req_id, job->pkgid, (int)job->target_uid, job->args);
795         argv = __generate_argv(args);
796
797         pid = __fork_and_exec_with_args(argv, APPFW_UID);
798
799         g_strfreev(argv);
800
801         return pid;
802 }
803
804 static int __process_enable_pkg(struct backend_job *job)
805 {
806         char *backend_cmd;
807         char **argv;
808         char args[MAX_PKG_ARGS_LEN];
809         pkgmgrinfo_pkginfo_h pkginfo_h;
810         bool is_readonly;
811         bool is_global;
812         int ret;
813         int pid;
814
815         backend_cmd = job->backend_path;
816         if (backend_cmd == NULL)
817                 return -1;
818
819         ret = pkgmgrinfo_pkginfo_get_usr_disabled_pkginfo(
820                         job->pkgid, job->target_uid, &pkginfo_h);
821         if (ret != PMINFO_R_OK) {
822                 ERR("Failed to get appinfo");
823                 return -1;
824         }
825
826         ret = pkgmgrinfo_pkginfo_is_global(pkginfo_h, &is_global);
827         if (ret != PMINFO_R_OK) {
828                 ERR("Failed to get global value");
829                 pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo_h);
830                 return -1;
831         }
832
833         if ((is_global && job->target_uid != GLOBAL_USER) ||
834                         (!is_global && job->target_uid == GLOBAL_USER)) {
835                 ERR("Invalid attempt to enable pkg");
836                 pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo_h);
837                 return -1;
838         }
839
840         ret = pkgmgrinfo_pkginfo_is_readonly(pkginfo_h, &is_readonly);
841         if (ret != PMINFO_R_OK) {
842                 ERR("Failed to get readonly value");
843                 pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo_h);
844                 return -1;
845         }
846
847         snprintf(args, sizeof(args), "%s -k %s -u %d -A %s %s",
848                         backend_cmd, job->req_id, (int)job->target_uid,
849                         job->pkgid, (is_readonly) ? "--preload" : "");
850         argv = __generate_argv(args);
851         pid = __fork_and_exec_with_args(argv, APPFW_UID);
852
853         g_strfreev(argv);
854         pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo_h);
855
856         return pid;
857 }
858
859 static int __process_disable_pkg(struct backend_job *job)
860 {
861         char *backend_cmd;
862         char **argv;
863         char args[MAX_PKG_ARGS_LEN];
864         pkgmgrinfo_pkginfo_h pkginfo_h;
865         bool is_readonly;
866         bool is_global;
867         int ret;
868         int pid;
869
870         backend_cmd = job->backend_path;
871         if (backend_cmd == NULL)
872                 return -1;
873
874         ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(
875                         job->pkgid, job->target_uid, &pkginfo_h);
876         if (ret != PMINFO_R_OK) {
877                 ERR("Failed to get appinfo");
878                 return -1;
879         }
880
881         ret = pkgmgrinfo_pkginfo_is_global(pkginfo_h, &is_global);
882         if (ret != PMINFO_R_OK) {
883                 ERR("Failed to get global value");
884                 pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo_h);
885                 return -1;
886         }
887
888         if ((is_global && job->target_uid != GLOBAL_USER) ||
889                         (!is_global && job->target_uid == GLOBAL_USER)) {
890                 ERR("Invalid attempt to disable pkg");
891                 pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo_h);
892                 return -1;
893         }
894
895         ret = pkgmgrinfo_pkginfo_is_readonly(pkginfo_h, &is_readonly);
896         if (ret != PMINFO_R_OK) {
897                 ERR("Failed to get readonly value");
898                 pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo_h);
899                 return -1;
900         }
901
902         snprintf(args, sizeof(args), "%s -k %s -u %d -D %s %s",
903                         backend_cmd, job->req_id, (int)job->target_uid,
904                         job->pkgid, (is_readonly) ? "--preload" : "");
905         argv = __generate_argv(args);
906
907         pid = __fork_and_exec_with_args(argv, APPFW_UID);
908
909         g_strfreev(argv);
910
911         pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo_h);
912         return pid;
913 }
914
915 static int __process_register_pkg_update_info(struct backend_job *job)
916 {
917         int ret;
918
919         if (!job->extra_data) {
920                 _return_value_to_caller(job->req_id,
921                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
922                 return -1;
923         }
924
925         ret = pkgmgr_parser_register_pkg_update_info_in_usr_db(
926                         (pkgmgrinfo_updateinfo_h)job->extra_data, job->target_uid);
927         if (ret == PMINFO_R_OK)
928                 _return_value_to_caller(job->req_id,
929                                 g_variant_new("(i)", PKGMGR_R_OK));
930         else
931                 _return_value_to_caller(job->req_id,
932                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
933
934         pkgmgrinfo_updateinfo_destroy(job->extra_data);
935         job->extra_data = NULL;
936
937         return ret;
938 }
939
940 static int __process_unregister_pkg_update_info(struct backend_job *job)
941 {
942         int ret = pkgmgr_parser_unregister_pkg_update_info_in_usr_db
943                         (job->pkgid, job->target_uid);
944
945         if (ret == PMINFO_R_OK)
946                 _return_value_to_caller(job->req_id,
947                                 g_variant_new("(i)", PKGMGR_R_OK));
948         else
949                 _return_value_to_caller(job->req_id,
950                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
951         return ret;
952 }
953
954 static int __process_unregister_all_pkg_update_info(struct backend_job *job)
955 {
956         int ret = pkgmgr_parser_unregister_all_pkg_update_info_in_usr_db(
957                         job->target_uid);
958
959         if (ret != PMINFO_R_OK) {
960                 _return_value_to_caller(job->req_id,
961                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
962                 return ret;
963         }
964
965         if (__is_admin_user(job->caller_uid)) {
966                 ret = pkgmgr_parser_unregister_all_pkg_update_info_in_usr_db(
967                                 GLOBAL_USER);
968                 if (ret != PMINFO_R_OK) {
969                         _return_value_to_caller(job->req_id,
970                                         g_variant_new("(i)", PKGMGR_R_ESYSTEM));
971                         return ret;
972                 }
973         }
974         _return_value_to_caller(job->req_id,
975                         g_variant_new("(i)", PKGMGR_R_OK));
976
977         return ret;
978 }
979
980 static int __process_enable_app(struct backend_job *job)
981 {
982         int ret = -1;
983         bool is_global = false;
984
985         /* get actual pkgid and replace it to appid which is currently stored
986          * at pkgid variable
987          */
988         ret = __change_job_info(job, job->target_uid, &is_global);
989         if (ret != PMINFO_R_OK || strlen(job->appid) == 0) {
990                 _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->pkgid,
991                                 PKGMGR_INSTALLER_START_KEY_STR,
992                                 PKGMGR_INSTALLER_APP_ENABLE_EVENT_STR,
993                                 job->req_type);
994                 _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->pkgid,
995                                 PKGMGR_INSTALLER_END_KEY_STR,
996                                 PKGMGR_INSTALLER_FAIL_EVENT_STR,
997                                 job->req_type);
998                 return ret;
999         }
1000
1001         _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->appid,
1002                         PKGMGR_INSTALLER_START_KEY_STR,
1003                         PKGMGR_INSTALLER_APP_ENABLE_EVENT_STR, job->req_type);
1004
1005         ret = pkgmgr_parser_update_app_disable_info_in_usr_db(job->appid,
1006                         job->target_uid, 0);
1007         if (ret != PMINFO_R_OK)
1008                 _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->appid,
1009                                 PKGMGR_INSTALLER_END_KEY_STR,
1010                                 PKGMGR_INSTALLER_FAIL_EVENT_STR,
1011                                 job->req_type);
1012         else
1013                 _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->appid,
1014                                 PKGMGR_INSTALLER_END_KEY_STR,
1015                                 PKGMGR_INSTALLER_OK_EVENT_STR,
1016                                 job->req_type);
1017
1018         return ret;
1019 }
1020
1021 static int __process_disable_app(struct backend_job *job)
1022 {
1023         int ret = -1;
1024         bool is_global = false;
1025
1026         /* get actual pkgid and replace it to appid which is currently stored
1027          * at pkgid variable
1028          */
1029         ret = __change_job_info(job, job->target_uid, &is_global);
1030         if (ret != PMINFO_R_OK || strlen(job->appid) == 0) {
1031                 _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->pkgid,
1032                                 PKGMGR_INSTALLER_START_KEY_STR,
1033                                 PKGMGR_INSTALLER_APP_DISABLE_EVENT_STR,
1034                                 job->req_type);
1035                 _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->pkgid,
1036                                 PKGMGR_INSTALLER_END_KEY_STR,
1037                                 PKGMGR_INSTALLER_FAIL_EVENT_STR,
1038                                 job->req_type);
1039                 return ret;
1040         }
1041
1042         _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->appid,
1043                         PKGMGR_INSTALLER_START_KEY_STR,
1044                         PKGMGR_INSTALLER_APP_DISABLE_EVENT_STR, job->req_type);
1045
1046         ret = __kill_app(job->appid, job->target_uid);
1047         if (ret != 0) {
1048                 _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->appid,
1049                                 PKGMGR_INSTALLER_END_KEY_STR,
1050                                 PKGMGR_INSTALLER_FAIL_EVENT_STR,
1051                                 job->req_type);
1052         }
1053
1054         ret = pkgmgr_parser_update_app_disable_info_in_usr_db(job->appid,
1055                         job->target_uid, 1);
1056         if (ret != PMINFO_R_OK)
1057                 _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->appid,
1058                                 PKGMGR_INSTALLER_END_KEY_STR,
1059                                 PKGMGR_INSTALLER_FAIL_EVENT_STR,
1060                                 job->req_type);
1061         else
1062                 _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->appid,
1063                                 PKGMGR_INSTALLER_END_KEY_STR,
1064                                 PKGMGR_INSTALLER_OK_EVENT_STR,
1065                                 job->req_type);
1066
1067         return ret;
1068 }
1069
1070 static int __process_enable_global_app_for_uid(struct backend_job *job)
1071 {
1072         int ret = -1;
1073         bool is_global = true;
1074
1075         /* get actual pkgid and replace it to appid which is currently stored
1076          * at pkgid variable
1077          */
1078         ret = __change_job_info(job, job->target_uid, &is_global);
1079         if (ret != PMINFO_R_OK || strlen(job->appid) == 0) {
1080                 _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->pkgid,
1081                                 PKGMGR_INSTALLER_START_KEY_STR,
1082                                 PKGMGR_INSTALLER_APP_ENABLE_EVENT_STR,
1083                                 job->req_type);
1084                 _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->pkgid,
1085                                 PKGMGR_INSTALLER_END_KEY_STR,
1086                                 PKGMGR_INSTALLER_FAIL_EVENT_STR,
1087                                 job->req_type);
1088                 return ret;
1089         }
1090
1091         _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->appid,
1092                         PKGMGR_INSTALLER_START_KEY_STR,
1093                         PKGMGR_INSTALLER_APP_ENABLE_EVENT_STR,
1094                         job->req_type);
1095
1096         ret = pkgmgr_parser_update_global_app_disable_for_uid_info_in_db(
1097                         job->appid, job->target_uid, 0);
1098         if (ret != PMINFO_R_OK)
1099                 _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->appid,
1100                                 PKGMGR_INSTALLER_END_KEY_STR,
1101                                 PKGMGR_INSTALLER_FAIL_EVENT_STR,
1102                                 job->req_type);
1103         else
1104                 _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->appid,
1105                                 PKGMGR_INSTALLER_END_KEY_STR,
1106                                 PKGMGR_INSTALLER_OK_EVENT_STR,
1107                                 job->req_type);
1108
1109         return ret;
1110 }
1111
1112 static int __process_disable_global_app_for_uid(struct backend_job *job)
1113 {
1114         int ret = -1;
1115         bool is_global = true;
1116
1117         /* get actual pkgid and replace it to appid which is currently stored
1118          * at pkgid variable
1119          */
1120         ret = __change_job_info(job, GLOBAL_USER, &is_global);
1121         if (ret != PMINFO_R_OK || strlen(job->appid) == 0) {
1122                 _send_app_signal(job->target_uid, job->req_id,
1123                                 job->pkgid, job->pkgid,
1124                                 PKGMGR_INSTALLER_START_KEY_STR,
1125                                 PKGMGR_INSTALLER_APP_DISABLE_EVENT_STR,
1126                                 job->req_type);
1127                 _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->pkgid,
1128                                 PKGMGR_INSTALLER_END_KEY_STR,
1129                                 PKGMGR_INSTALLER_FAIL_EVENT_STR,
1130                                 job->req_type);
1131                 return ret;
1132         }
1133
1134         _send_app_signal(job->target_uid, job->req_id,
1135                         job->pkgid, job->appid,
1136                         PKGMGR_INSTALLER_START_KEY_STR,
1137                         PKGMGR_INSTALLER_APP_DISABLE_EVENT_STR,
1138                         job->req_type);
1139
1140         ret = __kill_app(job->appid, job->target_uid);
1141         ret = pkgmgr_parser_update_global_app_disable_for_uid_info_in_db(
1142                         job->appid, job->target_uid, 1);
1143
1144         if (ret != PMINFO_R_OK)
1145                 _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->appid,
1146                                 PKGMGR_INSTALLER_END_KEY_STR,
1147                                 PKGMGR_INSTALLER_FAIL_EVENT_STR,
1148                                 job->req_type);
1149         else
1150                 _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->appid,
1151                                 PKGMGR_INSTALLER_END_KEY_STR,
1152                                 PKGMGR_INSTALLER_OK_EVENT_STR,
1153                                 job->req_type);
1154
1155         return ret;
1156 }
1157
1158 static int __process_getsize(struct backend_job *job)
1159 {
1160         static const char backend_cmd[] = "/usr/bin/pkg_getsize";
1161         char **argv;
1162         char args[MAX_PKG_ARGS_LEN];
1163         int pid;
1164
1165         snprintf(args, sizeof(args), "%s %s %s %d -k %s -u %d",
1166                         backend_cmd, job->pkgid, job->args, job->caller_uid,
1167                         job->req_id, job->target_uid);
1168         argv = __generate_argv(args);
1169         pid = __fork_and_exec_with_args(argv, APPFW_UID);
1170
1171         g_strfreev(argv);
1172
1173         return pid;
1174 }
1175
1176 static int __process_getsize_sync(struct backend_job *job)
1177 {
1178         static const char backend_cmd[] = "/usr/bin/pkg_getsize";
1179         char **argv;
1180         char args[MAX_PKG_ARGS_LEN];
1181         char fifo_path[PATH_MAX];
1182         int pid;
1183
1184         snprintf(fifo_path, sizeof(fifo_path), "/tmp/pkgmgr/%s",
1185                         job->req_id);
1186
1187         job->extra = calloc(1, sizeof(struct job_extra_info));
1188         if (!job->extra) {
1189                 ERR("memory alloc failed");
1190                 goto error;
1191         }
1192
1193         job->extra->getsize_fifo = strdup(fifo_path);
1194         if (!job->extra->getsize_fifo) {
1195                 ERR("out of memory");
1196                 goto error;
1197         }
1198
1199         if (mkfifo(job->extra->getsize_fifo, 0600) < 0) {
1200                 ERR("failed to mkfifo");
1201                 goto error;
1202         }
1203
1204         snprintf(args, sizeof(args), "%s %s %s %d -k %s -u %d --sync",
1205                         backend_cmd, job->pkgid, job->args, job->caller_uid,
1206                         job->req_id, job->target_uid);
1207         argv = __generate_argv(args);
1208         pid = __fork_and_exec_with_args(argv, APPFW_UID);
1209
1210         g_strfreev(argv);
1211
1212         if (pid < 0) {
1213                 ERR("failed to execute backend");
1214                 goto error;
1215         }
1216         if (__setup_size_info_io(job) < 0) {
1217                 ERR("failed to setup io handler");
1218                 goto error;
1219         }
1220
1221         return pid;
1222
1223 error:
1224         _return_value_to_caller(job->req_id,
1225                 g_variant_new("(ix)", PKGMGR_R_ERROR, -1));
1226         return -1;
1227 }
1228
1229 static int __process_cleardata(struct backend_job *job)
1230 {
1231         static const char *backend_cmd = "/usr/bin/pkg_cleardata";
1232         char **argv;
1233         char args[MAX_PKG_ARGS_LEN];
1234         int pid;
1235
1236         if ((int)job->target_uid < REGULAR_USER)
1237                 return -1;
1238
1239         snprintf(args, sizeof(args), "%s -d -n %s -u %d",
1240                         backend_cmd, job->pkgid, job->target_uid);
1241         argv = __generate_argv(args);
1242         pid = __fork_and_exec_with_args(argv, APPFW_UID);
1243
1244         g_strfreev(argv);
1245         return pid;
1246 }
1247
1248 static int __process_clearcache(struct backend_job *job)
1249 {
1250         static const char *backend_cmd = "/usr/bin/pkg_cleardata";
1251         char **argv;
1252         char args[MAX_PKG_ARGS_LEN];
1253         int pid;
1254
1255         if ((int)job->target_uid < REGULAR_USER)
1256                 return -1;
1257
1258         snprintf(args, sizeof(args), "%s -c -n %s -u %d",
1259                         backend_cmd, job->pkgid, job->target_uid);
1260         argv = __generate_argv(args);
1261         pid = __fork_and_exec_with_args(argv, APPFW_UID);
1262
1263         g_strfreev(argv);
1264         return pid;
1265 }
1266
1267 static int __process_kill(struct backend_job *job)
1268 {
1269         int ret;
1270         pkgmgrinfo_pkginfo_h handle;
1271         pkgcmd_data *pdata;
1272
1273         ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(job->pkgid, job->target_uid,
1274                         &handle);
1275         if (ret < 0) {
1276                 ERR("Failed to get handle");
1277                 _return_value_to_caller(job->req_id,
1278                                 g_variant_new("(ii)", PKGMGR_R_ERROR, 0));
1279                 return -1;
1280         }
1281
1282         pdata = calloc(1, sizeof(pkgcmd_data));
1283         if (pdata == NULL) {
1284                 ERR("memory alloc failed");
1285                 _return_value_to_caller(job->req_id,
1286                                 g_variant_new("(ii)", PKGMGR_R_ENOMEM, 0));
1287                 return -1;
1288         }
1289         pdata->cmd = strdup("kill");
1290         if (pdata->cmd == NULL) {
1291                 ERR("out of memory");
1292                 _return_value_to_caller(job->req_id,
1293                                 g_variant_new("(ii)", PKGMGR_R_ENOMEM, 0));
1294                 free(pdata);
1295                 return -1;
1296         }
1297         pdata->uid = job->target_uid;
1298         ret = pkgmgrinfo_appinfo_get_usr_list(handle, PMINFO_ALL_APP,
1299                         __pkgcmd_app_cb, pdata, job->target_uid);
1300
1301         _return_value_to_caller(job->req_id,
1302                         g_variant_new("(ii)", PKGMGR_R_OK, pdata->pid));
1303
1304         free(pdata->cmd);
1305         free(pdata);
1306         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1307         if (ret < 0) {
1308                 ERR("pkgmgrinfo_appinfo_get_list() failed");
1309                 return -1;
1310         }
1311
1312         return 0;
1313 }
1314
1315 static int __process_check(struct backend_job *job)
1316 {
1317         int ret;
1318         pkgmgrinfo_pkginfo_h handle;
1319         pkgcmd_data *pdata;
1320
1321         ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(job->pkgid, job->target_uid,
1322                         &handle);
1323         if (ret < 0) {
1324                 ERR("Failed to get handle");
1325                 _return_value_to_caller(job->req_id,
1326                                 g_variant_new("(ii)", PKGMGR_R_ERROR, 0));
1327                 return -1;
1328         }
1329
1330         pdata = calloc(1, sizeof(pkgcmd_data));
1331         if (pdata == NULL) {
1332                 ERR("memory alloc failed");
1333                 _return_value_to_caller(job->req_id,
1334                                 g_variant_new("(ii)", PKGMGR_R_ENOMEM, 0));
1335                 return -1;
1336         }
1337         pdata->cmd = strdup("check");
1338         if (pdata->cmd == NULL) {
1339                 ERR("out of memory");
1340                 _return_value_to_caller(job->req_id,
1341                                 g_variant_new("(ii)", PKGMGR_R_ENOMEM, 0));
1342                 free(pdata);
1343                 return -1;
1344         }
1345         pdata->uid = job->target_uid;
1346         ret = pkgmgrinfo_appinfo_get_usr_list(handle, PMINFO_ALL_APP,
1347                         __pkgcmd_app_cb, pdata, job->target_uid);
1348
1349         _return_value_to_caller(job->req_id,
1350                         g_variant_new("(ii)", PKGMGR_R_OK, pdata->pid));
1351
1352         free(pdata->cmd);
1353         free(pdata);
1354         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1355         if (ret < 0) {
1356                 ERR("pkgmgrinfo_appinfo_get_list() failed");
1357                 return -1;
1358         }
1359
1360         return 0;
1361 }
1362
1363 static int __process_generate_license_request(struct backend_job *job)
1364 {
1365         int ret;
1366         char *resp_data;
1367         char req_data[MAX_PKG_ARGS_LEN];
1368         unsigned int req_data_len;
1369         char license_url[MAX_PKG_ARGS_LEN];
1370         unsigned int license_url_len;
1371
1372         resp_data = job->args;
1373         req_data_len = sizeof(req_data);
1374         license_url_len = sizeof(license_url);
1375
1376         ret = drm_tizen_generate_license_request(resp_data, strlen(resp_data),
1377                         req_data, &req_data_len, license_url, &license_url_len);
1378         if (ret != TADC_SUCCESS) {
1379                 ERR("drm_tizen_generate_license_request failed: %d", ret);
1380                 _return_value_to_caller(job->req_id, g_variant_new("(iss)",
1381                                         PKGMGR_R_ESYSTEM, "", ""));
1382                 is_drm_busy = false;
1383                 return -1;
1384         }
1385
1386         _return_value_to_caller(job->req_id,
1387                         g_variant_new("(iss)", PKGMGR_R_OK, req_data,
1388                                 license_url));
1389         is_drm_busy = true;
1390         return 0;
1391 }
1392
1393 static int __process_register_license(struct backend_job *job)
1394 {
1395         int ret;
1396         char *resp_data;
1397
1398         resp_data = job->args;
1399
1400         ret = drm_tizen_register_license(resp_data, strlen(resp_data));
1401         if (ret != TADC_SUCCESS) {
1402                 ERR("drm_tizen_register_license failed: %d", ret);
1403                 _return_value_to_caller(job->req_id,
1404                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1405                 is_drm_busy = false;
1406                 return -1;
1407         }
1408
1409         _return_value_to_caller(job->req_id,
1410                         g_variant_new("(i)", PKGMGR_R_OK));
1411
1412         return 0;
1413 }
1414
1415 static int __process_decrypt_package(struct backend_job *job)
1416 {
1417         int ret;
1418         char *drm_file_path;
1419         char *decrypted_file_path;
1420
1421         drm_file_path = job->pkgid;
1422         decrypted_file_path = job->args;
1423
1424         /* TODO: check ownership of decrypted file */
1425         ret = drm_tizen_decrypt_package(drm_file_path, strlen(drm_file_path),
1426                         decrypted_file_path, strlen(decrypted_file_path));
1427         if (ret != TADC_SUCCESS) {
1428                 ERR("drm_tizen_register_license failed: %d", ret);
1429                 _return_value_to_caller(job->req_id,
1430                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1431                 is_drm_busy = false;
1432                 return -1;
1433         }
1434
1435         _return_value_to_caller(job->req_id,
1436                         g_variant_new("(i)", PKGMGR_R_OK));
1437         is_drm_busy = false;
1438
1439         return 0;
1440 }
1441
1442 static int __process_update_app_splash_screen(struct backend_job *job, int flag)
1443 {
1444         int ret;
1445         bool is_global = false;
1446         const char *val;
1447
1448         ret = __change_job_info(job, job->target_uid, &is_global);
1449         if (ret != PMINFO_R_OK || strlen(job->appid) == 0)
1450                 return -1;
1451
1452         val = flag ? PKGMGR_INSTALLER_APP_ENABLE_SPLASH_SCREEN_EVENT_STR :
1453                 PKGMGR_INSTALLER_APP_DISABLE_SPLASH_SCREEN_EVENT_STR;
1454         _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->appid,
1455                         PKGMGR_INSTALLER_START_KEY_STR, val, job->req_type);
1456
1457         if (is_global)
1458                 ret = pkgmgr_parser_update_global_app_splash_screen_display_info_in_usr_db(job->appid, job->target_uid, flag);
1459         else
1460                 ret = pkgmgr_parser_update_app_splash_screen_display_info_in_usr_db(
1461                         job->appid, job->target_uid, flag);
1462         if (ret != PMINFO_R_OK)
1463                 _send_app_signal(job->target_uid, job->req_id, job->pkgid,
1464                                 job->appid, PKGMGR_INSTALLER_END_KEY_STR,
1465                                 PKGMGR_INSTALLER_FAIL_EVENT_STR,
1466                                 job->req_type);
1467         else
1468                 _send_app_signal(job->target_uid, job->req_id, job->pkgid,
1469                                 job->appid, PKGMGR_INSTALLER_END_KEY_STR,
1470                                 PKGMGR_INSTALLER_OK_EVENT_STR,
1471                                 job->req_type);
1472
1473         return ret;
1474 }
1475
1476 static int __process_set_restriction_mode(struct backend_job *job)
1477 {
1478         int ret;
1479         int mode;
1480
1481         mode = atoi(job->args);
1482         ret = _set_restriction_mode(job->target_uid, job->pkgid, mode);
1483
1484         _return_value_to_caller(job->req_id,
1485                         g_variant_new("(i)", ret));
1486
1487         return ret;
1488 }
1489
1490 static int __process_unset_restriction_mode(struct backend_job *job)
1491 {
1492         int ret;
1493         int mode;
1494
1495         mode = atoi(job->args);
1496         ret = _unset_restriction_mode(job->target_uid, job->pkgid, mode);
1497
1498         _return_value_to_caller(job->req_id,
1499                         g_variant_new("(i)", ret));
1500
1501         return ret;
1502 }
1503
1504 static int __process_get_restriction_mode(struct backend_job *job)
1505 {
1506         int ret;
1507         int mode = -1;
1508
1509         ret = _get_restriction_mode(job->target_uid, job->pkgid, &mode);
1510
1511         _return_value_to_caller(job->req_id,
1512                         g_variant_new("(ii)", mode, ret));
1513
1514         return ret;
1515 }
1516
1517 static int __process_set_app_label(struct backend_job *job)
1518 {
1519         int ret;
1520
1521         ret = pkgmgr_parser_update_app_label_info_in_usr_db(job->pkgid,
1522                         job->target_uid, job->args);
1523         _return_value_to_caller(job->req_id, g_variant_new("(i)", ret));
1524
1525         return ret;
1526 }
1527
1528 static int __process_migrate_external_image(struct backend_job *job)
1529 {
1530         char *backend_cmd;
1531         char **argv;
1532         char args[MAX_PKG_ARGS_LEN];
1533         int pid;
1534
1535         backend_cmd = job->backend_path;
1536         if (backend_cmd == NULL)
1537                 return -1;
1538
1539         snprintf(args, sizeof(args), "%s -k %s --migrate-extimg %s -u %d %s",
1540                         backend_cmd, job->req_id, job->pkgid,
1541                         (int)job->target_uid, job->args);
1542
1543         argv = __generate_argv(args);
1544
1545         pid = __fork_and_exec_with_args(argv, APPFW_UID);
1546         g_strfreev(argv);
1547
1548         return pid;
1549 }
1550
1551 static int __post_process(int ret, int x, struct backend_job *job)
1552 {
1553         if (ret < 0) {
1554                 __set_backend_free(x);
1555                 _free_backend_job(job);
1556         } else {
1557                 g_hash_table_insert(backend_info_table, (gpointer)ret,
1558                                 (gpointer)job);
1559         }
1560         return 0;
1561 }
1562
1563 gboolean queue_job(void *data)
1564 {
1565         struct backend_job *job = NULL;
1566         int x;
1567         int ret;
1568
1569         /* Pop a job from queue */
1570         for (x = 0; x < num_of_backends; x++) {
1571                 if (__is_backend_busy(x))
1572                         continue;
1573
1574                 job = _pop_queue(x);
1575                 if (job)
1576                         break;
1577         }
1578
1579         /* all backend messages queue are empty or busy */
1580         if (x == num_of_backends || job == NULL) {
1581                 DBG("no job available");
1582                 return FALSE;
1583         }
1584
1585         /* set current backend job */
1586         DBG("handle request type [%d]", job->req_type);
1587
1588 #ifdef TIZEN_FEATURE_CSR
1589         if (job->req_type == REQUEST_TYPE_INSTALL ||
1590                         job->req_type == REQUEST_TYPE_MOUNT_INSTALL ||
1591                         job->req_type == REQUEST_TYPE_REINSTALL) {
1592                 ret = __check_csr(job->pkgid);
1593                 if (ret != 0) {
1594                         ret = -1;
1595                         _send_fail_signal(job);
1596                         _free_backend_job(job);
1597                         return TRUE;
1598                 }
1599         }
1600 #endif
1601
1602         switch (job->req_type) {
1603         case REQUEST_TYPE_INSTALL:
1604                 __set_backend_busy(x);
1605                 ret = __process_install(job);
1606                 __post_process(ret, x, job);
1607                 break;
1608         case REQUEST_TYPE_MOUNT_INSTALL:
1609                 __set_backend_busy(x);
1610                 ret = __process_mount_install(job);
1611                 __post_process(ret, x, job);
1612                 break;
1613         case REQUEST_TYPE_REINSTALL:
1614                 __set_backend_busy(x);
1615                 ret = __process_reinstall(job);
1616                 __post_process(ret, x, job);
1617                 break;
1618         case REQUEST_TYPE_UNINSTALL:
1619                 __set_backend_busy(x);
1620                 ret = __process_uninstall(job);
1621                 __post_process(ret, x, job);
1622                 break;
1623         case REQUEST_TYPE_MOVE:
1624                 __set_backend_busy(x);
1625                 ret = __process_move(job);
1626                 __post_process(ret, x, job);
1627                 break;
1628         case REQUEST_TYPE_ENABLE_PKG:
1629                 __set_backend_busy(x);
1630                 ret = __process_enable_pkg(job);
1631                 if (ret < 0)
1632                         _send_fail_signal(job);
1633                 __post_process(ret, x, job);
1634                 break;
1635         case REQUEST_TYPE_DISABLE_PKG:
1636                 __set_backend_busy(x);
1637                 ret = __process_disable_pkg(job);
1638                 if (ret < 0)
1639                         _send_fail_signal(job);
1640                 __post_process(ret, x, job);
1641                 break;
1642         case REQUEST_TYPE_REGISTER_PKG_UPDATE_INFO:
1643                 ret = __process_register_pkg_update_info(job);
1644                 _free_backend_job(job);
1645                 break;
1646         case REQUEST_TYPE_UNREGISTER_PKG_UPDATE_INFO:
1647                 ret = __process_unregister_pkg_update_info(job);
1648                 _free_backend_job(job);
1649                 break;
1650         case REQUEST_TYPE_UNREGISTER_ALL_PKG_UPDATE_INFO:
1651                 ret = __process_unregister_all_pkg_update_info(job);
1652                 _free_backend_job(job);
1653                 break;
1654         case REQUEST_TYPE_ENABLE_APP:
1655                 ret = __process_enable_app(job);
1656                 _free_backend_job(job);
1657                 break;
1658         case REQUEST_TYPE_DISABLE_APP:
1659                 ret = __process_disable_app(job);
1660                 _free_backend_job(job);
1661                 break;
1662         case REQUEST_TYPE_GETSIZE:
1663                 __set_backend_busy(x);
1664                 ret = __process_getsize(job);
1665                 __post_process(ret, x, job);
1666                 break;
1667         case REQUEST_TYPE_GETSIZE_SYNC:
1668                 __set_backend_busy(x);
1669                 ret = __process_getsize_sync(job);
1670                 if (ret < 0)
1671                         __free_extra_info(job);
1672                 __post_process(ret, x, job);
1673                 break;
1674         case REQUEST_TYPE_CLEARDATA:
1675                 __set_backend_busy(x);
1676                 ret = __process_cleardata(job);
1677                 __post_process(ret, x, job);
1678                 break;
1679         case REQUEST_TYPE_CLEARCACHE:
1680                 __set_backend_busy(x);
1681                 ret = __process_clearcache(job);
1682                 __post_process(ret, x, job);
1683                 break;
1684         case REQUEST_TYPE_ENABLE_GLOBAL_APP_FOR_UID:
1685                 ret = __process_enable_global_app_for_uid(job);
1686                 _free_backend_job(job);
1687                 break;
1688         case REQUEST_TYPE_DISABLE_GLOBAL_APP_FOR_UID:
1689                 ret = __process_disable_global_app_for_uid(job);
1690                 _free_backend_job(job);
1691                 break;
1692         case REQUEST_TYPE_KILL:
1693                 ret = __process_kill(job);
1694                 _free_backend_job(job);
1695                 break;
1696         case REQUEST_TYPE_CHECK:
1697                 ret = __process_check(job);
1698                 _free_backend_job(job);
1699                 break;
1700         case REQUEST_TYPE_GENERATE_LICENSE_REQUEST:
1701                 ret = __process_generate_license_request(job);
1702                 _free_backend_job(job);
1703                 break;
1704         case REQUEST_TYPE_REGISTER_LICENSE:
1705                 ret = __process_register_license(job);
1706                 _free_backend_job(job);
1707                 break;
1708         case REQUEST_TYPE_DECRYPT_PACKAGE:
1709                 ret = __process_decrypt_package(job);
1710                 _free_backend_job(job);
1711                 break;
1712         case REQUEST_TYPE_ENABLE_APP_SPLASH_SCREEN:
1713                 ret = __process_update_app_splash_screen(job, 1);
1714                 _free_backend_job(job);
1715                 break;
1716         case REQUEST_TYPE_DISABLE_APP_SPLASH_SCREEN:
1717                 ret = __process_update_app_splash_screen(job, 0);
1718                 _free_backend_job(job);
1719                 break;
1720         case REQUEST_TYPE_SET_RESTRICTION_MODE:
1721                 ret = __process_set_restriction_mode(job);
1722                 _free_backend_job(job);
1723                 break;
1724         case REQUEST_TYPE_UNSET_RESTRICTION_MODE:
1725                 ret = __process_unset_restriction_mode(job);
1726                 _free_backend_job(job);
1727                 break;
1728         case REQUEST_TYPE_GET_RESTRICTION_MODE:
1729                 ret = __process_get_restriction_mode(job);
1730                 _free_backend_job(job);
1731                 break;
1732         case REQUEST_TYPE_SET_APP_LABEL:
1733                 ret = __process_set_app_label(job);
1734                 _free_backend_job(job);
1735                 break;
1736         case REQUEST_TYPE_MIGRATE_EXTERNAL_IMAGE:
1737                 __set_backend_busy(x);
1738                 ret = __process_migrate_external_image(job);
1739                 __post_process(ret, x, job);
1740                 break;
1741         default:
1742                 ret = -1;
1743                 break;
1744         }
1745
1746         return TRUE;
1747 }
1748
1749 int main(int argc, char *argv[])
1750 {
1751         int r;
1752
1753         DBG("server start");
1754
1755         if (__register_signal_handler()) {
1756                 ERR("failed to register signal handler");
1757                 return -1;
1758         }
1759
1760         r = _init_backend_queue();
1761         if (r) {
1762                 ERR("Queue Initialization Failed");
1763                 return -1;
1764         }
1765
1766         r = __init_backend_info();
1767         if (r) {
1768                 ERR("backend info init failed");
1769                 return -1;
1770         }
1771
1772         r = _init_request_handler();
1773         if (r) {
1774                 ERR("dbus init failed");
1775                 return -1;
1776         }
1777
1778 #if !GLIB_CHECK_VERSION(2, 35, 0)
1779         g_type_init();
1780 #endif
1781         mainloop = g_main_loop_new(NULL, FALSE);
1782         if (!mainloop) {
1783                 ERR("g_main_loop_new failed");
1784                 return -1;
1785         }
1786
1787         DBG("Main loop is created.");
1788
1789         g_main_loop_run(mainloop);
1790
1791         DBG("Quit main loop.");
1792         _fini_request_handler();
1793         __fini_backend_info();
1794         _fini_backend_queue();
1795
1796         g_source_remove(swid);
1797         g_io_channel_unref(sio);
1798
1799         DBG("package manager server terminated.");
1800
1801         return 0;
1802 }