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