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