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