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