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