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