c3d33d1b5c5f2c9d2caff8c0632a3144ca99105d
[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_APP ||
592                                 job->req_type == REQUEST_TYPE_ENABLE_APP) &&
593                         *is_global) {
594                 ret = PMINFO_R_ERROR;
595                 goto catch;
596         } else if ((job->req_type == REQUEST_TYPE_DISABLE_GLOBAL_APP_FOR_UID ||
597                                 job->req_type ==
598                                 REQUEST_TYPE_ENABLE_GLOBAL_APP_FOR_UID) &&
599                         !*is_global) {
600                 ret = PMINFO_R_ERROR;
601                 goto catch;
602         }
603
604         ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgid);
605         if (ret != PMINFO_R_OK)
606                 goto catch;
607
608         free(job->appid);
609         job->appid = strdup(job->pkgid);
610         free(job->pkgid);
611         job->pkgid = strdup(pkgid);
612
613 catch:
614         pkgmgrinfo_appinfo_destroy_appinfo(handle);
615
616         return ret;
617 }
618
619 static int __process_install(struct backend_job *job)
620 {
621         char *backend_cmd;
622         char **argv;
623         char args[MAX_PKG_ARGS_LEN];
624         int pid;
625
626         backend_cmd = job->backend_path;
627         if (backend_cmd == NULL)
628                 return -1;
629
630         snprintf(args, sizeof(args), "%s -k %s -i %s -u %d %s", backend_cmd,
631                         job->req_id, job->pkgid, (int)job->target_uid, job->args);
632
633         argv = __generate_argv(args);
634
635         pid = __fork_and_exec_with_args(argv, APPFW_UID);
636         g_strfreev(argv);
637
638         return pid;
639 }
640
641 static int __process_mount_install(struct backend_job *job)
642 {
643         char *backend_cmd;
644         char **argv;
645         char args[MAX_PKG_ARGS_LEN];
646         int pid;
647
648         backend_cmd = job->backend_path;
649         if (backend_cmd == NULL)
650                 return -1;
651
652         snprintf(args, sizeof(args), "%s -k %s -w %s -u %d %s", backend_cmd,
653                         job->req_id, job->pkgid, (int)job->target_uid, job->args);
654
655         argv = __generate_argv(args);
656
657         pid = __fork_and_exec_with_args(argv, APPFW_UID);
658         g_strfreev(argv);
659
660         return pid;
661 }
662
663 static int __process_reinstall(struct backend_job *job)
664 {
665         char *backend_cmd;
666         char **argv;
667         char args[MAX_PKG_ARGS_LEN];
668         int pid;
669
670         backend_cmd = job->backend_path;
671         if (backend_cmd == NULL)
672                 return -1;
673
674         snprintf(args, sizeof(args), "%s -k %s -r %s -u %d", backend_cmd,
675                         job->req_id, job->pkgid, (int)job->target_uid);
676         argv = __generate_argv(args);
677
678         pid = __fork_and_exec_with_args(argv, APPFW_UID);
679
680         g_strfreev(argv);
681
682         return pid;
683 }
684
685 static int __process_uninstall(struct backend_job *job)
686 {
687         char *backend_cmd;
688         char **argv;
689         char args[MAX_PKG_ARGS_LEN];
690         int pid;
691
692         backend_cmd = job->backend_path;
693         if (backend_cmd == NULL)
694                 return -1;
695
696         snprintf(args, sizeof(args), "%s -k %s -d %s -u %d", backend_cmd,
697                         job->req_id, job->pkgid, (int)job->target_uid);
698         argv = __generate_argv(args);
699
700         pid = __fork_and_exec_with_args(argv, APPFW_UID);
701
702         g_strfreev(argv);
703
704         return pid;
705 }
706
707 static int __process_move(struct backend_job *job)
708 {
709         char *backend_cmd;
710         char **argv;
711         char args[MAX_PKG_ARGS_LEN];
712         int pid;
713
714         backend_cmd = job->backend_path;
715         if (backend_cmd == NULL)
716                 return -1;
717
718         snprintf(args, sizeof(args), "%s -k %s -m %s -u %d -t %s", backend_cmd,
719                         job->req_id, job->pkgid, (int)job->target_uid, job->args);
720         argv = __generate_argv(args);
721
722         pid = __fork_and_exec_with_args(argv, APPFW_UID);
723
724         g_strfreev(argv);
725
726         return pid;
727 }
728
729 static int __process_enable_pkg(struct backend_job *job)
730 {
731         char *backend_cmd;
732         char **argv;
733         char args[MAX_PKG_ARGS_LEN];
734         pkgmgrinfo_pkginfo_h pkginfo_h;
735         bool is_readonly;
736         bool is_global;
737         int ret;
738         int pid;
739
740         backend_cmd = job->backend_path;
741         if (backend_cmd == NULL)
742                 return -1;
743
744         ret = pkgmgrinfo_pkginfo_get_usr_disabled_pkginfo(
745                         job->pkgid, job->target_uid, &pkginfo_h);
746         if (ret != PMINFO_R_OK) {
747                 ERR("Failed to get appinfo");
748                 return -1;
749         }
750
751         ret = pkgmgrinfo_pkginfo_is_global(pkginfo_h, &is_global);
752         if (ret != PMINFO_R_OK) {
753                 ERR("Failed to get global value");
754                 pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo_h);
755                 return -1;
756         }
757
758         if ((is_global && job->target_uid != GLOBAL_USER) ||
759                         (!is_global && job->target_uid == GLOBAL_USER)) {
760                 ERR("Invalid attempt to enable pkg");
761                 pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo_h);
762                 return -1;
763         }
764
765         ret = pkgmgrinfo_pkginfo_is_readonly(pkginfo_h, &is_readonly);
766         if (ret != PMINFO_R_OK) {
767                 ERR("Failed to get readonly value");
768                 pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo_h);
769                 return -1;
770         }
771
772         snprintf(args, sizeof(args), "%s -k %s -u %d -A %s %s",
773                         backend_cmd, job->req_id, (int)job->target_uid,
774                         job->pkgid, (is_readonly) ? "--preload" : "");
775         argv = __generate_argv(args);
776         pid = __fork_and_exec_with_args(argv, APPFW_UID);
777
778         g_strfreev(argv);
779         pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo_h);
780
781         return pid;
782 }
783
784 static int __process_disable_pkg(struct backend_job *job)
785 {
786         char *backend_cmd;
787         char **argv;
788         char args[MAX_PKG_ARGS_LEN];
789         pkgmgrinfo_pkginfo_h pkginfo_h;
790         bool is_readonly;
791         bool is_global;
792         int ret;
793         int pid;
794
795         backend_cmd = job->backend_path;
796         if (backend_cmd == NULL)
797                 return -1;
798
799         ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(
800                         job->pkgid, job->target_uid, &pkginfo_h);
801         if (ret != PMINFO_R_OK) {
802                 ERR("Failed to get appinfo");
803                 return -1;
804         }
805
806         ret = pkgmgrinfo_pkginfo_is_global(pkginfo_h, &is_global);
807         if (ret != PMINFO_R_OK) {
808                 ERR("Failed to get global value");
809                 pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo_h);
810                 return -1;
811         }
812
813         if ((is_global && job->target_uid != GLOBAL_USER) ||
814                         (!is_global && job->target_uid == GLOBAL_USER)) {
815                 ERR("Invalid attempt to disable pkg");
816                 pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo_h);
817                 return -1;
818         }
819
820         ret = pkgmgrinfo_pkginfo_is_readonly(pkginfo_h, &is_readonly);
821         if (ret != PMINFO_R_OK) {
822                 ERR("Failed to get readonly value");
823                 pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo_h);
824                 return -1;
825         }
826
827         snprintf(args, sizeof(args), "%s -k %s -u %d -D %s %s",
828                         backend_cmd, job->req_id, (int)job->target_uid,
829                         job->pkgid, (is_readonly) ? "--preload" : "");
830         argv = __generate_argv(args);
831
832         pid = __fork_and_exec_with_args(argv, APPFW_UID);
833
834         g_strfreev(argv);
835
836         pkgmgrinfo_pkginfo_destroy_pkginfo(pkginfo_h);
837         return pid;
838 }
839
840 static int __process_enable_app(struct backend_job *job)
841 {
842         int ret = -1;
843         bool is_global = false;
844
845         /* get actual pkgid and replace it to appid which is currently stored
846          * at pkgid variable
847          */
848         ret = __change_job_info(job, job->target_uid, &is_global);
849         if (ret != PMINFO_R_OK || strlen(job->appid) == 0) {
850                 _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->pkgid,
851                                 PKGMGR_INSTALLER_START_KEY_STR,
852                                 PKGMGR_INSTALLER_APP_ENABLE_EVENT_STR,
853                                 job->req_type);
854                 _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->pkgid,
855                                 PKGMGR_INSTALLER_END_KEY_STR,
856                                 PKGMGR_INSTALLER_FAIL_EVENT_STR,
857                                 job->req_type);
858                 return ret;
859         }
860
861         _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->appid,
862                         PKGMGR_INSTALLER_START_KEY_STR,
863                         PKGMGR_INSTALLER_APP_ENABLE_EVENT_STR, job->req_type);
864
865         ret = pkgmgr_parser_update_app_disable_info_in_usr_db(job->appid,
866                         job->target_uid, 0);
867         if (ret != PMINFO_R_OK)
868                 _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->appid,
869                                 PKGMGR_INSTALLER_END_KEY_STR,
870                                 PKGMGR_INSTALLER_FAIL_EVENT_STR,
871                                 job->req_type);
872         else
873                 _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->appid,
874                                 PKGMGR_INSTALLER_END_KEY_STR,
875                                 PKGMGR_INSTALLER_OK_EVENT_STR,
876                                 job->req_type);
877
878         return ret;
879 }
880
881 static int __process_disable_app(struct backend_job *job)
882 {
883         int ret = -1;
884         bool is_global = false;
885
886         /* get actual pkgid and replace it to appid which is currently stored
887          * at pkgid variable
888          */
889         ret = __change_job_info(job, job->target_uid, &is_global);
890         if (ret != PMINFO_R_OK || strlen(job->appid) == 0) {
891                 _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->pkgid,
892                                 PKGMGR_INSTALLER_START_KEY_STR,
893                                 PKGMGR_INSTALLER_APP_DISABLE_EVENT_STR,
894                                 job->req_type);
895                 _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->pkgid,
896                                 PKGMGR_INSTALLER_END_KEY_STR,
897                                 PKGMGR_INSTALLER_FAIL_EVENT_STR,
898                                 job->req_type);
899                 return ret;
900         }
901
902         _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->appid,
903                         PKGMGR_INSTALLER_START_KEY_STR,
904                         PKGMGR_INSTALLER_APP_DISABLE_EVENT_STR, job->req_type);
905
906         ret = __kill_app(job->appid, job->target_uid);
907         if (ret != 0) {
908                 _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->appid,
909                                 PKGMGR_INSTALLER_END_KEY_STR,
910                                 PKGMGR_INSTALLER_FAIL_EVENT_STR,
911                                 job->req_type);
912         }
913
914         ret = pkgmgr_parser_update_app_disable_info_in_usr_db(job->appid,
915                         job->target_uid, 1);
916         if (ret != PMINFO_R_OK)
917                 _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->appid,
918                                 PKGMGR_INSTALLER_END_KEY_STR,
919                                 PKGMGR_INSTALLER_FAIL_EVENT_STR,
920                                 job->req_type);
921         else
922                 _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->appid,
923                                 PKGMGR_INSTALLER_END_KEY_STR,
924                                 PKGMGR_INSTALLER_OK_EVENT_STR,
925                                 job->req_type);
926
927         return ret;
928 }
929
930 static int __process_enable_global_app_for_uid(struct backend_job *job)
931 {
932         int ret = -1;
933         bool is_global = true;
934
935         /* get actual pkgid and replace it to appid which is currently stored
936          * at pkgid variable
937          */
938         ret = __change_job_info(job, job->target_uid, &is_global);
939         if (ret != PMINFO_R_OK || strlen(job->appid) == 0) {
940                 _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->pkgid,
941                                 PKGMGR_INSTALLER_START_KEY_STR,
942                                 PKGMGR_INSTALLER_GLOBAL_APP_ENABLE_FOR_UID,
943                                 job->req_type);
944                 _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->pkgid,
945                                 PKGMGR_INSTALLER_END_KEY_STR,
946                                 PKGMGR_INSTALLER_FAIL_EVENT_STR,
947                                 job->req_type);
948                 return ret;
949         }
950
951         _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->appid,
952                         PKGMGR_INSTALLER_START_KEY_STR,
953                         PKGMGR_INSTALLER_GLOBAL_APP_ENABLE_FOR_UID,
954                         job->req_type);
955
956         ret = pkgmgr_parser_update_global_app_disable_for_uid_info_in_db(
957                         job->appid, job->target_uid, 0);
958         if (ret != PMINFO_R_OK)
959                 _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->appid,
960                                 PKGMGR_INSTALLER_END_KEY_STR,
961                                 PKGMGR_INSTALLER_FAIL_EVENT_STR,
962                                 job->req_type);
963         else
964                 _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->appid,
965                                 PKGMGR_INSTALLER_END_KEY_STR,
966                                 PKGMGR_INSTALLER_OK_EVENT_STR,
967                                 job->req_type);
968
969         return ret;
970 }
971
972 static int __process_disable_global_app_for_uid(struct backend_job *job)
973 {
974         int ret = -1;
975         bool is_global = true;
976
977         /* get actual pkgid and replace it to appid which is currently stored
978          * at pkgid variable
979          */
980         ret = __change_job_info(job, GLOBAL_USER, &is_global);
981         if (ret != PMINFO_R_OK || strlen(job->appid) == 0) {
982                 _send_app_signal(job->target_uid, job->req_id,
983                                 job->pkgid, job->pkgid,
984                                 PKGMGR_INSTALLER_START_KEY_STR,
985                                 PKGMGR_INSTALLER_GLOBAL_APP_DISABLE_FOR_UID,
986                                 job->req_type);
987                 _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->pkgid,
988                                 PKGMGR_INSTALLER_END_KEY_STR,
989                                 PKGMGR_INSTALLER_FAIL_EVENT_STR,
990                                 job->req_type);
991                 return ret;
992         }
993
994         _send_app_signal(job->target_uid, job->req_id,
995                         job->pkgid, job->appid,
996                         PKGMGR_INSTALLER_START_KEY_STR,
997                         PKGMGR_INSTALLER_GLOBAL_APP_DISABLE_FOR_UID,
998                         job->req_type);
999
1000         ret = __kill_app(job->appid, job->target_uid);
1001         ret = pkgmgr_parser_update_global_app_disable_for_uid_info_in_db(
1002                         job->appid, job->target_uid, 1);
1003
1004         if (ret != PMINFO_R_OK)
1005                 _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->appid,
1006                                 PKGMGR_INSTALLER_END_KEY_STR,
1007                                 PKGMGR_INSTALLER_FAIL_EVENT_STR,
1008                                 job->req_type);
1009         else
1010                 _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->appid,
1011                                 PKGMGR_INSTALLER_END_KEY_STR,
1012                                 PKGMGR_INSTALLER_OK_EVENT_STR,
1013                                 job->req_type);
1014
1015         return ret;
1016 }
1017
1018 static int __process_getsize(struct backend_job *job)
1019 {
1020         static const char backend_cmd[] = "/usr/bin/pkg_getsize";
1021         char **argv;
1022         char args[MAX_PKG_ARGS_LEN];
1023         int pid;
1024
1025         snprintf(args, sizeof(args), "%s %s %s %d -k %s -u %d",
1026                         backend_cmd, job->pkgid, job->args, job->caller_uid,
1027                         job->req_id, job->target_uid);
1028         argv = __generate_argv(args);
1029         pid = __fork_and_exec_with_args(argv, APPFW_UID);
1030
1031         g_strfreev(argv);
1032
1033         return pid;
1034 }
1035
1036 static int __process_cleardata(struct backend_job *job)
1037 {
1038         char *backend_cmd;
1039         char **argv;
1040         char args[MAX_PKG_ARGS_LEN];
1041         int pid;
1042
1043         backend_cmd = job->backend_path;
1044         if (backend_cmd == NULL)
1045                 return -1;
1046
1047         /* TODO: set movetype */
1048         snprintf(args, sizeof(args), "%s -k %s -c %s -u %d", backend_cmd,
1049                         job->req_id, job->pkgid, (int)job->target_uid);
1050         argv = __generate_argv(args);
1051
1052         pid = __fork_and_exec_with_args(argv, APPFW_UID);
1053
1054         g_strfreev(argv);
1055
1056         return pid;
1057 }
1058
1059 static int __process_clearcache(struct backend_job *job)
1060 {
1061         static const char *backend_cmd = "/usr/bin/pkg_clearcache";
1062         char **argv;
1063         char args[MAX_PKG_ARGS_LEN];
1064         int pid;
1065
1066         snprintf(args, sizeof(args), "%s %s", backend_cmd, job->pkgid);
1067         argv = __generate_argv(args);
1068         pid = __fork_and_exec_with_args(argv, job->target_uid);
1069
1070         g_strfreev(argv);
1071
1072         return pid;
1073 }
1074
1075 static int __process_kill(struct backend_job *job)
1076 {
1077         int ret;
1078         pkgmgrinfo_pkginfo_h handle;
1079         pkgcmd_data *pdata;
1080
1081         ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(job->pkgid, job->target_uid,
1082                         &handle);
1083         if (ret < 0) {
1084                 ERR("Failed to get handle");
1085                 _return_value_to_caller(job->req_id,
1086                                 g_variant_new("(ii)", PKGMGR_R_ERROR, 0));
1087                 return -1;
1088         }
1089
1090         pdata = calloc(1, sizeof(pkgcmd_data));
1091         if (pdata == NULL) {
1092                 ERR("memory alloc failed");
1093                 _return_value_to_caller(job->req_id,
1094                                 g_variant_new("(ii)", PKGMGR_R_ENOMEM, 0));
1095                 return -1;
1096         }
1097         pdata->cmd = strdup("kill");
1098         if (pdata->cmd == NULL) {
1099                 ERR("out of memory");
1100                 _return_value_to_caller(job->req_id,
1101                                 g_variant_new("(ii)", PKGMGR_R_ENOMEM, 0));
1102                 free(pdata);
1103                 return -1;
1104         }
1105         pdata->uid = job->target_uid;
1106         ret = pkgmgrinfo_appinfo_get_usr_list(handle, PMINFO_ALL_APP,
1107                         __pkgcmd_app_cb, pdata, job->target_uid);
1108
1109         _return_value_to_caller(job->req_id,
1110                         g_variant_new("(ii)", PKGMGR_R_OK, pdata->pid));
1111
1112         free(pdata->cmd);
1113         free(pdata);
1114         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1115         if (ret < 0) {
1116                 ERR("pkgmgrinfo_appinfo_get_list() failed");
1117                 return -1;
1118         }
1119
1120         return 0;
1121 }
1122
1123 static int __process_check(struct backend_job *job)
1124 {
1125         int ret;
1126         pkgmgrinfo_pkginfo_h handle;
1127         pkgcmd_data *pdata;
1128
1129         ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(job->pkgid, job->target_uid,
1130                         &handle);
1131         if (ret < 0) {
1132                 ERR("Failed to get handle");
1133                 _return_value_to_caller(job->req_id,
1134                                 g_variant_new("(ii)", PKGMGR_R_ERROR, 0));
1135                 return -1;
1136         }
1137
1138         pdata = calloc(1, sizeof(pkgcmd_data));
1139         if (pdata == NULL) {
1140                 ERR("memory alloc failed");
1141                 _return_value_to_caller(job->req_id,
1142                                 g_variant_new("(ii)", PKGMGR_R_ENOMEM, 0));
1143                 return -1;
1144         }
1145         pdata->cmd = strdup("check");
1146         if (pdata->cmd == NULL) {
1147                 ERR("out of memory");
1148                 _return_value_to_caller(job->req_id,
1149                                 g_variant_new("(ii)", PKGMGR_R_ENOMEM, 0));
1150                 free(pdata);
1151                 return -1;
1152         }
1153         pdata->uid = job->target_uid;
1154         ret = pkgmgrinfo_appinfo_get_usr_list(handle, PMINFO_ALL_APP,
1155                         __pkgcmd_app_cb, pdata, job->target_uid);
1156
1157         _return_value_to_caller(job->req_id,
1158                         g_variant_new("(ii)", PKGMGR_R_OK, pdata->pid));
1159
1160         free(pdata->cmd);
1161         free(pdata);
1162         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1163         if (ret < 0) {
1164                 ERR("pkgmgrinfo_appinfo_get_list() failed");
1165                 return -1;
1166         }
1167
1168         return 0;
1169 }
1170
1171 static int __process_generate_license_request(struct backend_job *job)
1172 {
1173         int ret;
1174         char *resp_data;
1175         char req_data[MAX_PKG_ARGS_LEN];
1176         unsigned int req_data_len;
1177         char license_url[MAX_PKG_ARGS_LEN];
1178         unsigned int license_url_len;
1179
1180         resp_data = job->args;
1181         req_data_len = sizeof(req_data);
1182         license_url_len = sizeof(license_url);
1183
1184         ret = drm_tizen_generate_license_request(resp_data, strlen(resp_data),
1185                         req_data, &req_data_len, license_url, &license_url_len);
1186         if (ret != TADC_SUCCESS) {
1187                 ERR("drm_tizen_generate_license_request failed: %d", ret);
1188                 _return_value_to_caller(job->req_id, g_variant_new("(iss)",
1189                                         PKGMGR_R_ESYSTEM, "", ""));
1190                 return -1;
1191         }
1192
1193         _return_value_to_caller(job->req_id,
1194                         g_variant_new("(iss)", PKGMGR_R_OK, req_data,
1195                                 license_url));
1196
1197         return 0;
1198 }
1199
1200 static int __process_register_license(struct backend_job *job)
1201 {
1202         int ret;
1203         char *resp_data;
1204
1205         resp_data = job->args;
1206
1207         ret = drm_tizen_register_license(resp_data, strlen(resp_data));
1208         if (ret != TADC_SUCCESS) {
1209                 ERR("drm_tizen_register_license failed: %d", ret);
1210                 _return_value_to_caller(job->req_id,
1211                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1212                 return -1;
1213         }
1214
1215         _return_value_to_caller(job->req_id,
1216                         g_variant_new("(i)", PKGMGR_R_OK));
1217
1218         return 0;
1219 }
1220
1221 static int __process_decrypt_package(struct backend_job *job)
1222 {
1223         int ret;
1224         char *drm_file_path;
1225         char *decrypted_file_path;
1226
1227         drm_file_path = job->pkgid;
1228         decrypted_file_path = job->args;
1229
1230         /* TODO: check ownership of decrypted file */
1231         ret = drm_tizen_decrypt_package(drm_file_path, strlen(drm_file_path),
1232                         decrypted_file_path, strlen(decrypted_file_path));
1233         if (ret != TADC_SUCCESS) {
1234                 ERR("drm_tizen_register_license failed: %d", ret);
1235                 _return_value_to_caller(job->req_id,
1236                                 g_variant_new("(i)", PKGMGR_R_ESYSTEM));
1237                 return -1;
1238         }
1239
1240         _return_value_to_caller(job->req_id,
1241                         g_variant_new("(i)", PKGMGR_R_OK));
1242
1243         return 0;
1244 }
1245
1246 static int __process_update_app_splash_screen(struct backend_job *job, int flag)
1247 {
1248         int ret;
1249         bool is_global = false;
1250         const char *val;
1251
1252         ret = __change_job_info(job, job->target_uid, &is_global);
1253         if (ret != PMINFO_R_OK || strlen(job->appid) == 0)
1254                 return -1;
1255
1256         val = flag ? PKGMGR_INSTALLER_APP_ENABLE_SPLASH_SCREEN_EVENT_STR :
1257                 PKGMGR_INSTALLER_APP_DISABLE_SPLASH_SCREEN_EVENT_STR;
1258         _send_app_signal(job->target_uid, job->req_id, job->pkgid, job->appid,
1259                         PKGMGR_INSTALLER_START_KEY_STR, val, job->req_type);
1260
1261         if (is_global)
1262                 ret = pkgmgr_parser_update_global_app_splash_screen_display_info_in_usr_db(job->appid, job->target_uid, flag);
1263         else
1264                 ret = pkgmgr_parser_update_app_splash_screen_display_info_in_usr_db(
1265                         job->appid, job->target_uid, flag);
1266         if (ret != PMINFO_R_OK)
1267                 _send_app_signal(job->target_uid, job->req_id, job->pkgid,
1268                                 job->appid, PKGMGR_INSTALLER_END_KEY_STR,
1269                                 PKGMGR_INSTALLER_FAIL_EVENT_STR,
1270                                 job->req_type);
1271         else
1272                 _send_app_signal(job->target_uid, job->req_id, job->pkgid,
1273                                 job->appid, PKGMGR_INSTALLER_END_KEY_STR,
1274                                 PKGMGR_INSTALLER_OK_EVENT_STR,
1275                                 job->req_type);
1276
1277         return ret;
1278 }
1279
1280 static int __process_set_restriction_mode(struct backend_job *job)
1281 {
1282         int ret;
1283         int mode;
1284
1285         mode = atoi(job->args);
1286         ret = _set_restriction_mode(job->target_uid, job->pkgid, mode);
1287
1288         _return_value_to_caller(job->req_id,
1289                         g_variant_new("(i)", ret));
1290
1291         return ret;
1292 }
1293
1294 static int __process_unset_restriction_mode(struct backend_job *job)
1295 {
1296         int ret;
1297         int mode;
1298
1299         mode = atoi(job->args);
1300         ret = _unset_restriction_mode(job->target_uid, job->pkgid, mode);
1301
1302         _return_value_to_caller(job->req_id,
1303                         g_variant_new("(i)", ret));
1304
1305         return ret;
1306 }
1307
1308 static int __process_get_restriction_mode(struct backend_job *job)
1309 {
1310         int ret;
1311         int mode = -1;
1312
1313         ret = _get_restriction_mode(job->target_uid, job->pkgid, &mode);
1314
1315         _return_value_to_caller(job->req_id,
1316                         g_variant_new("(ii)", mode, ret));
1317
1318         return ret;
1319 }
1320
1321 static int __process_set_app_label(struct backend_job *job)
1322 {
1323         int ret;
1324
1325         ret = pkgmgr_parser_update_app_label_info_in_usr_db(job->pkgid,
1326                         job->target_uid, job->args);
1327         _return_value_to_caller(job->req_id, g_variant_new("(i)", ret));
1328
1329         return ret;
1330 }
1331
1332 gboolean queue_job(void *data)
1333 {
1334         struct backend_job *job = NULL;
1335         int x;
1336         int ret;
1337
1338         /* Pop a job from queue */
1339         for (x = 0; x < num_of_backends; x++) {
1340                 if (__is_backend_busy(x))
1341                         continue;
1342
1343                 job = _pop_queue(x);
1344                 if (job)
1345                         break;
1346         }
1347
1348         /* all backend messages queue are empty or busy */
1349         if (x == num_of_backends || job == NULL) {
1350                 DBG("no job left");
1351                 return FALSE;
1352         }
1353
1354         /* set current backend job */
1355         DBG("handle request type [%d]", job->req_type);
1356
1357 #ifdef TIZEN_FEATURE_CSR
1358         if (job->req_type == REQUEST_TYPE_INSTALL ||
1359                         job->req_type == REQUEST_TYPE_MOUNT_INSTALL ||
1360                         job->req_type == REQUEST_TYPE_REINSTALL) {
1361                 ret = __check_csr(job->pkgid);
1362                 if (ret != 0) {
1363                         ret = -1;
1364                         _send_fail_signal(job);
1365                         _free_backend_job(job);
1366                         return FALSE;
1367                 }
1368         }
1369 #endif
1370
1371         switch (job->req_type) {
1372         case REQUEST_TYPE_INSTALL:
1373                 __set_backend_busy(x);
1374                 ret = __process_install(job);
1375                 g_hash_table_insert(backend_info_table, (gpointer)ret,
1376                                 (gpointer)job);
1377                 break;
1378         case REQUEST_TYPE_MOUNT_INSTALL:
1379                 __set_backend_busy(x);
1380                 ret = __process_mount_install(job);
1381                 g_hash_table_insert(backend_info_table, (gpointer)ret,
1382                                 (gpointer)job);
1383                 break;
1384         case REQUEST_TYPE_REINSTALL:
1385                 __set_backend_busy(x);
1386                 ret = __process_reinstall(job);
1387                 g_hash_table_insert(backend_info_table, (gpointer)ret,
1388                                 (gpointer)job);
1389                 break;
1390         case REQUEST_TYPE_UNINSTALL:
1391                 __set_backend_busy(x);
1392                 ret = __process_uninstall(job);
1393                 g_hash_table_insert(backend_info_table, (gpointer)ret,
1394                                 (gpointer)job);
1395                 break;
1396         case REQUEST_TYPE_MOVE:
1397                 __set_backend_busy(x);
1398                 ret = __process_move(job);
1399                 g_hash_table_insert(backend_info_table, (gpointer)ret,
1400                                 (gpointer)job);
1401                 break;
1402         case REQUEST_TYPE_ENABLE_PKG:
1403                 __set_backend_busy(x);
1404                 ret = __process_enable_pkg(job);
1405                 if (ret == -1) {
1406                         _send_fail_signal(job);
1407                         __set_backend_free(x);
1408                         _free_backend_job(job);
1409                 } else {
1410                         g_hash_table_insert(backend_info_table, (gpointer)ret,
1411                                         (gpointer)job);
1412                 }
1413                 break;
1414         case REQUEST_TYPE_DISABLE_PKG:
1415                 __set_backend_busy(x);
1416                 ret = __process_disable_pkg(job);
1417                 if (ret == -1) {
1418                         _send_fail_signal(job);
1419                         __set_backend_free(x);
1420                         _free_backend_job(job);
1421                 } else {
1422                         g_hash_table_insert(backend_info_table, (gpointer)ret,
1423                                         (gpointer)job);
1424                 }
1425                 break;
1426         case REQUEST_TYPE_ENABLE_APP:
1427                 ret = __process_enable_app(job);
1428                 _free_backend_job(job);
1429                 break;
1430         case REQUEST_TYPE_DISABLE_APP:
1431                 ret = __process_disable_app(job);
1432                 _free_backend_job(job);
1433                 break;
1434         case REQUEST_TYPE_GETSIZE:
1435                 __set_backend_busy(x);
1436                 ret = __process_getsize(job);
1437                 g_hash_table_insert(backend_info_table, (gpointer)ret,
1438                                 (gpointer)job);
1439                 break;
1440         case REQUEST_TYPE_CLEARDATA:
1441                 __set_backend_busy(x);
1442                 ret = __process_cleardata(job);
1443                 g_hash_table_insert(backend_info_table, (gpointer)ret,
1444                                 (gpointer)job);
1445                 break;
1446         case REQUEST_TYPE_CLEARCACHE:
1447                 __set_backend_busy(x);
1448                 ret = __process_clearcache(job);
1449                 g_hash_table_insert(backend_info_table, (gpointer)ret,
1450                                 (gpointer)job);
1451                 break;
1452         case REQUEST_TYPE_ENABLE_GLOBAL_APP_FOR_UID:
1453                 ret = __process_enable_global_app_for_uid(job);
1454                 _free_backend_job(job);
1455                 break;
1456         case REQUEST_TYPE_DISABLE_GLOBAL_APP_FOR_UID:
1457                 ret = __process_disable_global_app_for_uid(job);
1458                 _free_backend_job(job);
1459                 break;
1460         case REQUEST_TYPE_KILL:
1461                 ret = __process_kill(job);
1462                 _free_backend_job(job);
1463                 break;
1464         case REQUEST_TYPE_CHECK:
1465                 ret = __process_check(job);
1466                 _free_backend_job(job);
1467                 break;
1468         case REQUEST_TYPE_GENERATE_LICENSE_REQUEST:
1469                 ret = __process_generate_license_request(job);
1470                 _free_backend_job(job);
1471                 break;
1472         case REQUEST_TYPE_REGISTER_LICENSE:
1473                 ret = __process_register_license(job);
1474                 _free_backend_job(job);
1475                 break;
1476         case REQUEST_TYPE_DECRYPT_PACKAGE:
1477                 ret = __process_decrypt_package(job);
1478                 _free_backend_job(job);
1479                 break;
1480         case REQUEST_TYPE_ENABLE_APP_SPLASH_SCREEN:
1481                 ret = __process_update_app_splash_screen(job, 1);
1482                 _free_backend_job(job);
1483                 break;
1484         case REQUEST_TYPE_DISABLE_APP_SPLASH_SCREEN:
1485                 ret = __process_update_app_splash_screen(job, 0);
1486                 _free_backend_job(job);
1487                 break;
1488         case REQUEST_TYPE_SET_RESTRICTION_MODE:
1489                 ret = __process_set_restriction_mode(job);
1490                 _free_backend_job(job);
1491                 break;
1492         case REQUEST_TYPE_UNSET_RESTRICTION_MODE:
1493                 ret = __process_unset_restriction_mode(job);
1494                 _free_backend_job(job);
1495                 break;
1496         case REQUEST_TYPE_GET_RESTRICTION_MODE:
1497                 ret = __process_get_restriction_mode(job);
1498                 _free_backend_job(job);
1499                 break;
1500         case REQUEST_TYPE_SET_APP_LABEL:
1501                 ret = __process_set_app_label(job);
1502                 _free_backend_job(job);
1503                 break;
1504         default:
1505                 ret = -1;
1506                 break;
1507         }
1508
1509         return FALSE;
1510 }
1511
1512 int main(int argc, char *argv[])
1513 {
1514         int r;
1515
1516         DBG("server start");
1517
1518         r = _init_backend_queue();
1519         if (r) {
1520                 DBG("Queue Initialization Failed");
1521                 return -1;
1522         }
1523
1524         r = __init_backend_info();
1525         if (r) {
1526                 DBG("backend info init failed");
1527                 return -1;
1528         }
1529
1530         r = _init_request_handler();
1531         if (r) {
1532                 ERR("dbus init failed");
1533                 return -1;
1534         }
1535
1536         if (__register_signal_handler()) {
1537                 ERR("failed to register signal handler");
1538                 return -1;
1539         }
1540
1541 #if !GLIB_CHECK_VERSION(2, 35, 0)
1542         g_type_init();
1543 #endif
1544         mainloop = g_main_loop_new(NULL, FALSE);
1545         if (!mainloop) {
1546                 ERR("g_main_loop_new failed");
1547                 return -1;
1548         }
1549
1550         DBG("Main loop is created.");
1551
1552         g_main_loop_run(mainloop);
1553
1554         DBG("Quit main loop.");
1555         _fini_request_handler();
1556         __fini_backend_info();
1557         _fini_backend_queue();
1558
1559         DBG("package manager server terminated.");
1560
1561         return 0;
1562 }