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