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