Pass it's own uid when calling not 'usr' prefixed api
[platform/core/appfw/slp-pkgmgr.git] / client / src / pkgmgr.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 <unistd.h>
27 #include <dlfcn.h>
28 #include <dirent.h>
29 #include <fcntl.h>
30 #include <sys/wait.h>
31 #include <sys/time.h>
32
33 #include <glib.h>
34
35 #include <pkgmgr-info.h>
36 #include <iniparser.h>
37 /* For multi-user support */
38 #include <tzplatform_config.h>
39
40 #include "package-manager.h"
41 #include "pkgmgr-internal.h"
42 #include "pkgmgr-debug.h"
43 #include "pkgmgr-api.h"
44 #include "comm_client.h"
45
46 #define PKG_TMP_PATH tzplatform_mkpath(TZ_USER_APP, "tmp")
47
48 #define BINSH_NAME      "/bin/sh"
49 #define BINSH_SIZE      7
50
51 #define GLOBAL_USER tzplatform_getuid(TZ_SYS_GLOBALAPP_USER)
52 #define REGULAR_USER 5000
53
54 static inline uid_t _getuid(void)
55 {
56         uid_t uid = getuid();
57
58         if (uid < REGULAR_USER)
59                 return GLOBAL_USER;
60         else
61                 return uid;
62 }
63
64 static int _get_request_id()
65 {
66         static int internal_req_id = 1;
67
68         return internal_req_id++;
69 }
70
71 typedef struct _req_cb_info {
72         int request_id;
73         char *req_key;
74         pkgmgr_handler event_cb;
75         pkgmgr_app_handler app_event_cb;
76         void *data;
77         struct _req_cb_info *next;
78 } req_cb_info;
79
80 typedef struct _listen_cb_info {
81         int request_id;
82         pkgmgr_handler event_cb;
83         pkgmgr_app_handler app_event_cb;
84         void *data;
85         struct _listen_cb_info *next;
86 } listen_cb_info;
87
88 typedef struct _pkgmgr_client_t {
89         client_type ctype;
90         int status_type;
91         union {
92                 struct _request {
93                         comm_client *cc;
94                         req_cb_info *rhead;
95                 } request;
96                 struct _listening {
97                         comm_client *cc;
98                         listen_cb_info *lhead;
99                 } listening;
100         } info;
101         void *new_event_cb;
102         char *tep_path;
103         char *tep_move;
104 } pkgmgr_client_t;
105
106 typedef struct _iter_data {
107         pkgmgr_iter_fn iter_fn;
108         void *data;
109 } iter_data;
110
111 static int __xsystem(const char *argv[])
112 {
113         int status = 0;
114         pid_t pid;
115         pid = fork();
116         switch (pid) {
117         case -1:
118                 perror("fork failed");
119                 return -1;
120         case 0:
121                 /* child */
122                 execvp(argv[0], (char *const *)argv);
123                 _exit(-1);
124         default:
125                 /* parent */
126                 break;
127         }
128         if (waitpid(pid, &status, 0) == -1) {
129                 perror("waitpid failed");
130                 return -1;
131         }
132         if (WIFSIGNALED(status)) {
133                 perror("signal");
134                 return -1;
135         }
136         if (!WIFEXITED(status)) {
137                 /* shouldn't happen */
138                 perror("should not happen");
139                 return -1;
140         }
141         return WEXITSTATUS(status);
142 }
143
144 static void __error_to_string(int errnumber, char **errstr)
145 {
146         if (errstr == NULL)
147                 return;
148         switch (errnumber) {
149         case PKGCMD_ERR_PACKAGE_NOT_FOUND:
150                 *errstr = PKGCMD_ERR_PACKAGE_NOT_FOUND_STR;
151                 break;
152         case PKGCMD_ERR_PACKAGE_INVALID:
153                 *errstr = PKGCMD_ERR_PACKAGE_INVALID_STR;
154                 break;
155         case PKGCMD_ERR_PACKAGE_LOWER_VERSION:
156                 *errstr = PKGCMD_ERR_PACKAGE_LOWER_VERSION_STR;
157                 break;
158         case PKGCMD_ERR_PACKAGE_EXECUTABLE_NOT_FOUND:
159                 *errstr = PKGCMD_ERR_PACKAGE_EXECUTABLE_NOT_FOUND_STR;
160                 break;
161         case PKGCMD_ERR_MANIFEST_INVALID:
162                 *errstr = PKGCMD_ERR_MANIFEST_INVALID_STR;
163                 break;
164         case PKGCMD_ERR_CONFIG_NOT_FOUND:
165                 *errstr = PKGCMD_ERR_CONFIG_NOT_FOUND_STR;
166                 break;
167         case PKGCMD_ERR_CONFIG_INVALID:
168                 *errstr = PKGCMD_ERR_CONFIG_INVALID_STR;
169                 break;
170         case PKGCMD_ERR_SIGNATURE_NOT_FOUND:
171                 *errstr = PKGCMD_ERR_SIGNATURE_NOT_FOUND_STR;
172                 break;
173         case PKGCMD_ERR_SIGNATURE_INVALID:
174                 *errstr = PKGCMD_ERR_SIGNATURE_INVALID_STR;
175                 break;
176         case PKGCMD_ERR_SIGNATURE_VERIFICATION_FAILED:
177                 *errstr = PKGCMD_ERR_SIGNATURE_VERIFICATION_FAILED_STR;
178                 break;
179         case PKGCMD_ERR_ROOT_CERTIFICATE_NOT_FOUND:
180                 *errstr = PKGCMD_ERR_ROOT_CERTIFICATE_NOT_FOUND_STR;
181                 break;
182         case PKGCMD_ERR_CERTIFICATE_INVALID:
183                 *errstr = PKGCMD_ERR_CERTIFICATE_INVALID_STR;
184                 break;
185         case PKGCMD_ERR_CERTIFICATE_CHAIN_VERIFICATION_FAILED:
186                 *errstr = PKGCMD_ERR_CERTIFICATE_CHAIN_VERIFICATION_FAILED_STR;
187                 break;
188         case PKGCMD_ERR_CERTIFICATE_EXPIRED:
189                 *errstr = PKGCMD_ERR_CERTIFICATE_EXPIRED_STR;
190                 break;
191         case PKGCMD_ERR_INVALID_PRIVILEGE:
192                 *errstr = PKGCMD_ERR_INVALID_PRIVILEGE_STR;
193                 break;
194         case PKGCMD_ERR_MENU_ICON_NOT_FOUND:
195                 *errstr = PKGCMD_ERR_MENU_ICON_NOT_FOUND_STR;
196                 break;
197         case PKGCMD_ERR_FATAL_ERROR:
198                 *errstr = PKGCMD_ERR_FATAL_ERROR_STR;
199                 break;
200         case PKGCMD_ERR_OUT_OF_STORAGE:
201                 *errstr = PKGCMD_ERR_OUT_OF_STORAGE_STR;
202                 break;
203         case PKGCMD_ERR_OUT_OF_MEMORY:
204                 *errstr = PKGCMD_ERR_OUT_OF_MEMORY_STR;
205                 break;
206         case PKGCMD_ERR_ARGUMENT_INVALID:
207                 *errstr = PKGCMD_ERR_ARGUMENT_INVALID_STR;
208                 break;
209         default:
210                 *errstr = PKGCMD_ERR_UNKNOWN_STR;
211                 break;
212         }
213 }
214
215 static void __add_op_cbinfo(pkgmgr_client_t * pc, int request_id,
216                             const char *req_key, pkgmgr_handler event_cb, void *new_event_cb,
217                             void *data)
218 {
219         req_cb_info *cb_info;
220         req_cb_info *current;
221         req_cb_info *prev;
222
223         cb_info = (req_cb_info *) calloc(1, sizeof(req_cb_info));
224         if (cb_info == NULL) {
225                 DBG("calloc failed");
226                 return;
227         }
228         cb_info->request_id = request_id;
229         cb_info->req_key = strdup(req_key);
230         cb_info->event_cb = event_cb;
231         cb_info->data = data;
232         cb_info->next = NULL;
233         cb_info->app_event_cb = NULL;
234         pc->new_event_cb = new_event_cb;
235
236         if (pc->info.request.rhead == NULL)
237                 pc->info.request.rhead = cb_info;
238         else {
239                 current = prev = pc->info.request.rhead;
240                 while (current) {
241                         prev = current;
242                         current = current->next;
243                 }
244
245                 prev->next = cb_info;
246         }
247 }
248
249 static void __add_op_app_cbinfo(pkgmgr_client_t * pc, int request_id,
250                             const char *req_key, pkgmgr_app_handler app_event_cb, void *data)
251 {
252         req_cb_info *cb_info;
253         req_cb_info *current;
254         req_cb_info *prev;
255
256         cb_info = (req_cb_info *) calloc(1, sizeof(req_cb_info));
257         if (cb_info == NULL) {
258                 DBG("calloc failed");
259                 return;
260         }
261         cb_info->request_id = request_id;
262         cb_info->req_key = strdup(req_key);
263         cb_info->event_cb = NULL;
264         cb_info->app_event_cb = app_event_cb;
265         cb_info->data = data;
266         cb_info->next = NULL;
267         pc->new_event_cb = NULL;
268
269         if (pc->info.request.rhead == NULL)
270                 pc->info.request.rhead = cb_info;
271         else {
272                 current = prev = pc->info.request.rhead;
273                 while (current) {
274                         prev = current;
275                         current = current->next;
276                 }
277
278                 prev->next = cb_info;
279         }
280 }
281
282 static req_cb_info *__find_op_cbinfo(pkgmgr_client_t *pc, const char *req_key)
283 {
284         req_cb_info *tmp;
285
286         tmp = pc->info.request.rhead;
287
288         if (tmp == NULL) {
289                 ERR("tmp is NULL");
290                 return NULL;
291         }
292
293         DBG("tmp->req_key %s, req_key %s", tmp->req_key, req_key);
294
295         while (tmp) {
296                 if (strncmp(tmp->req_key, req_key, strlen(tmp->req_key)) == 0)
297                         return tmp;
298                 tmp = tmp->next;
299         }
300         return NULL;
301 }
302
303 static int __remove_stat_cbinfo(pkgmgr_client_t *pc)
304 {
305         listen_cb_info *info = pc->info.listening.lhead;
306         listen_cb_info *next = NULL;
307
308         while (info != NULL) {
309                 next = info->next;
310                 free(info);
311                 info = next;
312         }
313
314         pc->info.listening.lhead = NULL;
315         return 0;
316 }
317
318 static void __add_app_stat_cbinfo(pkgmgr_client_t *pc, int request_id,
319                               pkgmgr_app_handler event_cb, void *data)
320 {
321         listen_cb_info *cb_info;
322         listen_cb_info *current;
323         listen_cb_info *prev;
324
325         cb_info = (listen_cb_info *) calloc(1, sizeof(listen_cb_info));
326         if (cb_info == NULL) {
327                 DBG("calloc failed");
328                 return;
329         }
330         cb_info->request_id = request_id;
331         cb_info->app_event_cb = event_cb;
332         cb_info->data = data;
333         cb_info->next = NULL;
334
335         if (pc->info.listening.lhead == NULL)
336                 pc->info.listening.lhead = cb_info;
337         else {
338                 current = prev = pc->info.listening.lhead;
339                 while (current) {
340                         prev = current;
341                         current = current->next;
342                 }
343
344                 prev->next = cb_info;
345         }
346 }
347
348 static void __add_stat_cbinfo(pkgmgr_client_t *pc, int request_id,
349                               pkgmgr_handler event_cb, void *data)
350 {
351         listen_cb_info *cb_info;
352         listen_cb_info *current;
353         listen_cb_info *prev;
354
355         cb_info = (listen_cb_info *) calloc(1, sizeof(listen_cb_info));
356         if (cb_info == NULL) {
357                 DBG("calloc failed");
358                 return;
359         }
360         cb_info->request_id = request_id;
361         cb_info->event_cb = event_cb;
362         cb_info->data = data;
363         cb_info->next = NULL;
364
365         /* TODO - check the order of callback - FIFO or LIFO => Should be changed to LIFO */
366         if (pc->info.listening.lhead == NULL)
367                 pc->info.listening.lhead = cb_info;
368         else {
369                 current = prev = pc->info.listening.lhead;
370                 while (current) {
371                         prev = current;
372                         current = current->next;
373                 }
374
375                 prev->next = cb_info;
376         }
377 }
378
379 static void __operation_callback(void *cb_data, uid_t target_uid,
380                                  const char *req_id, const char *pkg_type,
381                                  const char *pkgid,  const char *appid,
382                                  const char *key,    const char *val)
383 {
384         pkgmgr_client_t *pc;
385         req_cb_info *cb_info;
386
387         pc = (pkgmgr_client_t *) cb_data;
388
389         /* find callback info */
390         cb_info = __find_op_cbinfo(pc, req_id);
391         if (cb_info == NULL) {
392                 ERR("cannot fint cb_info for req_id:%s", req_id);
393                 return;
394         }
395
396         /* call callback */
397         if (appid != NULL && strlen(appid) != 0) {
398                 /* run app callback */
399                 if (pc->new_event_cb)
400                         cb_info->app_event_cb(target_uid, cb_info->request_id,
401                                         pkg_type, pkgid, appid, key, val, pc,
402                                         cb_info->data);
403                 else
404                         cb_info->app_event_cb(target_uid, cb_info->request_id,
405                                         pkg_type, pkgid, appid, key, val, NULL,
406                                         cb_info->data);
407         } else {
408                 /* run pkg callback */
409                 if (pc->new_event_cb)
410                         cb_info->event_cb(target_uid, cb_info->request_id,
411                                         pkg_type, pkgid, key, val, pc,
412                                         cb_info->data);
413                 else
414                         cb_info->event_cb(target_uid, cb_info->request_id,
415                                         pkg_type, pkgid, key, val, NULL,
416                                         cb_info->data);
417         }
418
419         return;
420 }
421
422 static void __status_callback(void *cb_data, uid_t target_uid,
423                               const char *req_id, const char *pkg_type,
424                               const char *pkgid,  const char *appid,
425                               const char *key,    const char *val)
426 {
427         pkgmgr_client_t *pc;
428         listen_cb_info *tmp;
429
430         pc = (pkgmgr_client_t *) cb_data;
431
432         tmp = pc->info.listening.lhead;
433         while (tmp) {
434                 if (appid != NULL && strlen(appid) != 0) {
435                         /* run app callback */
436                         if (tmp->app_event_cb && tmp->app_event_cb(
437                                         target_uid, tmp->request_id, pkg_type, pkgid,
438                                         appid, key, val, NULL, tmp->data) != 0)
439                                 break;
440                 } else {
441                         /* run pkg callback */
442                         if (tmp->event_cb && tmp->event_cb(
443                                 target_uid, tmp->request_id, pkg_type, pkgid,
444                                 key, val, NULL, tmp->data) != 0)
445                                 break;
446                 }
447                 tmp = tmp->next;
448         }
449
450         return;
451 }
452
453 static inline int __read_proc(const char *path, char *buf, int size)
454 {
455         int fd = 0;
456         int ret = 0;
457
458         if (buf == NULL || path == NULL)
459                 return -1;
460
461         fd = open(path, O_RDONLY);
462         if (fd < 0)
463                 return -1;
464
465         ret = read(fd, buf, size - 1);
466         if (ret <= 0) {
467                 close(fd);
468                 return -1;
469         } else
470                 buf[ret] = 0;
471
472         close(fd);
473
474         return ret;
475 }
476
477 char *__proc_get_cmdline_bypid(int pid)
478 {
479         char buf[PKG_STRING_LEN_MAX] = {'\0', };
480         int ret = 0;
481
482         snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid);
483         ret = __read_proc(buf, buf, sizeof(buf));
484         if (ret <= 0)
485                 return NULL;
486
487         /* support app launched by shell script*/
488         if (strncmp(buf, BINSH_NAME, BINSH_SIZE) == 0)
489                 return strdup(&buf[BINSH_SIZE + 1]);
490         else
491                 return strdup(buf);
492 }
493
494 static inline int __pkgmgr_read_proc(const char *path, char *buf, int size)
495 {
496         int fd;
497         int ret;
498
499         if (buf == NULL || path == NULL)
500                 return -1;
501
502         fd = open(path, O_RDONLY);
503         if (fd < 0)
504                 return -1;
505
506         ret = read(fd, buf, size - 1);
507         if (ret <= 0) {
508                 close(fd);
509                 return -1;
510         } else
511                 buf[ret] = 0;
512
513         close(fd);
514
515         return ret;
516 }
517
518 static inline int __pkgmgr_find_pid_by_cmdline(const char *dname,
519                                       const char *cmdline, const char *apppath)
520 {
521         int pid = 0;
522
523         if (strncmp(cmdline, apppath, PKG_STRING_LEN_MAX-1) == 0) {
524                 pid = atoi(dname);
525                 if (pid != getpgid(pid))
526                         pid = 0;
527         }
528
529         return pid;
530 }
531
532 static int __sync_process(const char *req_key)
533 {
534         int ret;
535         char info_file[PKG_STRING_LEN_MAX] = {'\0', };
536         int result = -1;
537         int check_cnt = 0;
538         FILE *fp;
539         char buf[PKG_STRING_LEN_MAX] = {0, };
540
541         snprintf(info_file, PKG_STRING_LEN_MAX, "%s/%s", PKG_SIZE_INFO_PATH, req_key);
542         while(1)
543         {
544                 check_cnt++;
545
546                 if (access(info_file, F_OK) == 0) {
547                         fp = fopen(info_file, "r");
548                         if (fp == NULL) {
549                                 DBG("file is not generated yet.... wait\n");
550                                 usleep(100 * 1000);     /* 100ms sleep*/
551                                 continue;
552                         }
553
554                         if (fgets(buf, PKG_STRING_LEN_MAX, fp) == NULL) {
555                                 ERR("failed to read info file");
556                                 fclose(fp);
557                                 break;
558                         }
559                         fclose(fp);
560
561                         DBG("info_file file is generated, result = %s. \n", buf);
562                         result = atoi(buf);
563                         break;
564                 }
565
566                 DBG("file is not generated yet.... wait\n");
567                 usleep(100 * 1000);     /* 100ms sleep*/
568
569                 if (check_cnt > 6000) { /* 60s * 10 time over*/
570                         ERR("wait time over!!\n");
571                         break;
572                 }
573         }
574
575         ret = remove(info_file);
576         if (ret < 0)
577                 ERR("file is can not remove[%s, %d]\n", info_file, ret);
578
579         return result;
580 }
581
582 static int __csc_process(const char *csc_path, char *result_path)
583 {
584         int ret = 0;
585         int cnt = 0;
586         int count = 0;
587         int csc_fail = 0;
588         int fd = 0;
589         char *pkgtype = NULL;
590         char *des = NULL;
591         char buf[PKG_STRING_LEN_MAX] = {0,};
592         char type_buf[1024] = { 0 };
593         char des_buf[1024] = { 0 };
594         dictionary *csc = NULL;
595         FILE* file = NULL;
596
597         csc = iniparser_load(csc_path);
598         retvm_if(csc == NULL, PKGMGR_R_EINVAL, "cannot open parse file [%s]", csc_path);
599
600         file = fopen(result_path, "w");
601         tryvm_if(file == NULL, ret = PKGMGR_R_EINVAL, "cannot open result file [%s]", result_path);
602
603         count = iniparser_getint(csc, "csc packages:count", -1);
604         tryvm_if(count == 0, ret = PKGMGR_R_ERROR, "csc [%s] dont have packages", csc_path);
605
606         snprintf(buf, PKG_STRING_LEN_MAX, "[result]\n");
607         fwrite(buf, 1, strlen(buf), file);
608         snprintf(buf, PKG_STRING_LEN_MAX, "count = %d\n", count);
609         fwrite(buf, 1, strlen(buf), file);
610
611         for(cnt = 1 ; cnt <= count ; cnt++)
612         {
613                 snprintf(type_buf, PKG_STRING_LEN_MAX - 1, "csc packages:type_%03d", cnt);
614                 snprintf(des_buf, PKG_STRING_LEN_MAX - 1, "csc packages:description_%03d", cnt);
615
616                 pkgtype = iniparser_getstring(csc, type_buf, NULL);
617                 des = iniparser_getstring(csc, des_buf, NULL);
618                 ret = 0;
619
620                 if (pkgtype == NULL) {
621                         csc_fail++;
622                         snprintf(buf, PKG_STRING_LEN_MAX, "%s = Fail to get pkgtype\n", type_buf);
623                         fwrite(buf, 1, strlen(buf), file);
624                         continue;
625                 } else if (des == NULL) {
626                         csc_fail++;
627                         snprintf(buf, PKG_STRING_LEN_MAX, "%s = Fail to get description\n", des_buf);
628                         fwrite(buf, 1, strlen(buf), file);
629                         continue;
630                 }
631
632                 snprintf(buf, PKG_STRING_LEN_MAX, "type_%03d = %s\n", cnt, pkgtype);
633                 fwrite(buf, 1, strlen(buf), file);
634                 snprintf(buf, PKG_STRING_LEN_MAX, "description_%03d = %s\n", cnt, des);
635                 fwrite(buf, 1, strlen(buf), file);
636
637                 if (strcmp(pkgtype, "tpk") == 0) {
638                         const char *ospinstaller_argv[] = { "/usr/bin/osp-installer", "-c", des, NULL };
639                         ret = __xsystem(ospinstaller_argv);
640                 } else if (strcmp(pkgtype, "wgt")== 0) {
641                         const char *wrtinstaller_argv[] = { "/usr/bin/wrt-installer", "-c", des, NULL };
642                         ret = __xsystem(wrtinstaller_argv);
643                 } else {
644                         csc_fail++;
645                         ret = -1;
646                 }
647
648                 if (ret != 0) {
649                         char *errstr = NULL;
650                         __error_to_string(ret, &errstr);
651                         snprintf(buf, PKG_STRING_LEN_MAX, "result_%03d = fail[%s]\n", cnt, errstr);
652                 }
653                 else
654                         snprintf(buf, PKG_STRING_LEN_MAX, "result_%03d = success\n", cnt);
655
656                 fwrite(buf, 1, strlen(buf), file);
657         }
658
659 catch:
660         iniparser_freedict(csc);
661         if (file != NULL) {
662                 fflush(file);
663                 fd = fileno(file);
664                 fsync(fd);
665                 fclose(file);
666         }
667         return ret;
668 }
669
670 static int __get_size_process(pkgmgr_client * pc, const char *pkgid, uid_t uid,
671                 pkgmgr_getsize_type get_type, pkgmgr_handler event_cb,
672                 void *data)
673 {
674         GVariant *result;
675         int ret = PKGMGR_R_ECOMM;
676         char *req_key = NULL;
677         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
678
679         if (pc == NULL || pkgid == NULL) {
680                 ERR("invalid parameter");
681                 return PKGMGR_R_EINVAL;
682         }
683
684         if (mpc->ctype != PC_REQUEST) {
685                 ERR("mpc->ctype is not PC_REQUEST");
686                 return PKGMGR_R_EINVAL;
687         }
688         result = comm_client_request(mpc->info.request.cc, "getsize",
689                         g_variant_new("(usi)", uid, pkgid, get_type));
690         if (result == NULL)
691                 return PKGMGR_R_ECOMM;
692
693         g_variant_get(result, "(i&s)", &ret, &req_key);
694         if (req_key == NULL) {
695                 g_variant_unref(result);
696                 return PKGMGR_R_ECOMM;
697         }
698         if (ret != PKGMGR_R_OK) {
699                 g_variant_unref(result);
700                 return ret;
701         }
702
703         ret = __sync_process(req_key);
704         if (ret < 0)
705                 ERR("get size failed, ret=%d\n", ret);
706
707         g_variant_unref(result);
708
709         return ret;
710 }
711
712 static int __move_pkg_process(pkgmgr_client *pc, const char *pkgid,
713                 const char *pkg_type, uid_t uid, pkgmgr_move_type move_type,
714                 pkgmgr_handler event_cb, void *data)
715 {
716         int ret;
717
718         ret = pkgmgr_client_usr_move(pc, pkg_type, pkgid, move_type, 0, uid);
719         if (ret < 0) {
720                 ERR("move request failed");
721                 return ret;
722         }
723
724         /* FIXME */
725         ret = __sync_process(pkgid);
726         if (ret != 0)
727                 ERR("move pkg failed, ret=%d\n", ret);
728
729         return ret;
730 }
731
732 static int __check_app_process(pkgmgr_request_service_type service_type,
733                 pkgmgr_client *pc, const char *pkgid, uid_t uid, void *data)
734 {
735         GVariant *result = NULL;
736         int ret = PKGMGR_R_ECOMM;
737         pkgmgrinfo_pkginfo_h handle;
738         int pid = -1;
739         pkgmgr_client_t *mpc = (pkgmgr_client_t *) pc;
740
741         retvm_if(mpc->ctype != PC_REQUEST, PKGMGR_R_EINVAL, "mpc->ctype is not PC_REQUEST\n");
742
743         if (uid != GLOBAL_USER)
744                 ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &handle);
745         else
746                 ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &handle);
747         retvm_if(ret < 0, PKGMGR_R_ERROR, "pkgmgrinfo_pkginfo_get_pkginfo failed");
748
749         if (service_type == PM_REQUEST_KILL_APP)
750                 result = comm_client_request(mpc->info.request.cc, "kill",
751                                 g_variant_new("(us)", uid, pkgid));
752         else if (service_type == PM_REQUEST_CHECK_APP)
753                 result = comm_client_request(mpc->info.request.cc, "check",
754                                 g_variant_new("(us)", uid, pkgid));
755
756         if (result == NULL)
757                 return PKGMGR_R_ECOMM;
758         g_variant_get(result, "(i)", &ret);
759         g_variant_unref(result);
760         if (ret != PKGMGR_R_OK) {
761                 ERR("request failed, ret=%d", ret);
762                 return ret;
763         }
764
765         /* FIXME */
766         pid  = __sync_process(pkgid);
767         *(int *)data = pid;
768
769         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
770
771         return ret;
772
773 }
774
775 static int __request_size_info(pkgmgr_client *pc, uid_t uid)
776 {
777         GVariant *result;
778         int ret = PKGMGR_R_ECOMM;
779         char *req_key = NULL;
780         pkgmgr_client_t *mpc = (pkgmgr_client_t *) pc;
781
782         if (pc == NULL) {
783                 ERR("invalid parameter");
784                 return PKGMGR_R_EINVAL;
785         }
786
787         if (mpc->ctype != PC_REQUEST) {
788                 ERR("mpc->ctype is not PC_REQUEST");
789                 return PKGMGR_R_EINVAL;
790         }
791
792         result = comm_client_request(mpc->info.request.cc, "getsize",
793                         g_variant_new("(usi)", uid, "size_info", PM_GET_SIZE_INFO));
794         if (result == NULL)
795                 return PKGMGR_R_ECOMM;
796
797         g_variant_get(result, "(i&s)", &ret, &req_key);
798         if (req_key == NULL) {
799                 g_variant_unref(result);
800                 return PKGMGR_R_ECOMM;
801         }
802
803         g_variant_unref(result);
804
805         return ret;
806 }
807
808 static int __change_op_cb_for_getsize(pkgmgr_client *pc)
809 {
810         int ret = -1;
811
812         retvm_if(pc == NULL, PKGMGR_R_EINVAL, "package manager client pc is NULL");
813         pkgmgr_client_t *mpc = (pkgmgr_client_t *) pc;
814
815         /*  free listening head */
816         req_cb_info *tmp = NULL;
817         req_cb_info *prev = NULL;
818         for (tmp = mpc->info.request.rhead; tmp;) {
819                 prev = tmp;
820                 tmp = tmp->next;
821                 free(prev);
822         }
823
824         /* free dbus connection */
825         ret = comm_client_free(mpc->info.request.cc);
826         retvm_if(ret < 0, PKGMGR_R_ERROR, "comm_client_free() failed - %d", ret);
827
828         /* Manage pc for seperated event */
829         mpc->ctype = PC_REQUEST;
830         mpc->status_type = PKGMGR_CLIENT_STATUS_GET_SIZE;
831
832
833         mpc->info.request.cc = comm_client_new();
834         retvm_if(mpc->info.request.cc == NULL, PKGMGR_R_ERROR, "client creation failed");
835
836         ret = comm_client_set_status_callback(COMM_STATUS_BROADCAST_GET_SIZE, mpc->info.request.cc, __operation_callback, pc);
837         retvm_if(ret < 0, PKGMGR_R_ERROR, "set_status_callback() failed - %d", ret);
838
839         return PKGMGR_R_OK;
840 }
841
842 static int __change_op_cb_for_enable_disable(pkgmgr_client *pc, bool is_disable)
843 {
844         int ret = -1;
845
846         retvm_if(pc == NULL, PKGMGR_R_EINVAL, "package manager client pc is NULL");
847         pkgmgr_client_t *mpc = (pkgmgr_client_t *) pc;
848
849         /*  free listening head */
850         req_cb_info *tmp = NULL;
851         req_cb_info *prev = NULL;
852         for (tmp = mpc->info.request.rhead; tmp;) {
853                 prev = tmp;
854                 tmp = tmp->next;
855                 free(prev);
856         }
857
858         /* free dbus connection */
859         ret = comm_client_free(mpc->info.request.cc);
860         retvm_if(ret < 0, PKGMGR_R_ERROR, "comm_client_free() failed - %d", ret);
861
862         /* Manage pc for seperated event */
863         mpc->ctype = PC_REQUEST;
864         if (is_disable)
865                 mpc->status_type = PKGMGR_CLIENT_STATUS_DISABLE_APP;
866         else
867                 mpc->status_type = PKGMGR_CLIENT_STATUS_ENABLE_APP;
868
869
870         mpc->info.request.cc = comm_client_new();
871         retvm_if(mpc->info.request.cc == NULL, PKGMGR_R_ERROR, "client creation failed");
872
873         if (is_disable)
874                 ret = comm_client_set_status_callback(COMM_STATUS_BROADCAST_DISABLE_APP, mpc->info.request.cc, __operation_callback, pc);
875         else
876                 ret = comm_client_set_status_callback(COMM_STATUS_BROADCAST_ENABLE_APP, mpc->info.request.cc, __operation_callback, pc);
877         retvm_if(ret < 0, PKGMGR_R_ERROR, "set_status_callback() failed - %d", ret);
878
879         return PKGMGR_R_OK;
880 }
881
882 static int __get_pkg_size_info_cb(uid_t target_uid, int req_id, const char *req_type,
883                 const char *pkgid, const char *key,
884                 const char *value, const void *pc, void *user_data)
885 {
886         int ret = 0;
887         DBG("target_uid: %u, reqid: %d, req type: %s, pkgid: %s, unused key: %s, size info: %s",
888                         target_uid, req_id, req_type, pkgid, key, value);
889
890         pkg_size_info_t *size_info = (pkg_size_info_t *)malloc(sizeof(pkg_size_info_t));
891         retvm_if(size_info == NULL, -1, "The memory is insufficient.");
892
893         char *save_ptr = NULL;
894         char *token = strtok_r((char*)value, ":", &save_ptr);
895         tryvm_if(token == NULL, ret = -1, "failed to parse sizeinfo");
896         size_info->data_size = atoll(token);
897         token = strtok_r(NULL, ":", &save_ptr);
898         tryvm_if(token == NULL, ret = -1, "failed to parse sizeinfo");
899         size_info->cache_size = atoll(token);
900         token = strtok_r(NULL, ":", &save_ptr);
901         tryvm_if(token == NULL, ret = -1, "failed to parse sizeinfo");
902         size_info->app_size = atoll(token);
903         token = strtok_r(NULL, ":", &save_ptr);
904         tryvm_if(token == NULL, ret = -1, "failed to parse sizeinfo");
905         size_info->ext_data_size = atoll(token);
906         token = strtok_r(NULL, ":", &save_ptr);
907         tryvm_if(token == NULL, ret = -1, "failed to parse sizeinfo");
908         size_info->ext_cache_size = atoll(token);
909         token = strtok_r(NULL, ":", &save_ptr);
910         tryvm_if(token == NULL, ret = -1, "failed to parse sizeinfo");
911         size_info->ext_app_size = atoll(token);
912
913         DBG("data: %lld, cache: %lld, app: %lld, ext_data: %lld, ext_cache: %lld, ext_app: %lld",
914                         size_info->data_size, size_info->cache_size, size_info->app_size,
915                         size_info->ext_data_size, size_info->ext_cache_size, size_info->ext_app_size);
916
917         pkgmgr_client_t *pmc = (pkgmgr_client_t *)pc;
918         tryvm_if(pmc == NULL, ret = -1, "pkgmgr_client instance is null.");
919
920         if (strcmp(pkgid, PKG_SIZE_INFO_TOTAL) == 0)
921         {       // total package size info
922                 pkgmgr_total_pkg_size_info_receive_cb callback = (pkgmgr_total_pkg_size_info_receive_cb)(pmc->new_event_cb);
923                 callback((pkgmgr_client *)pc, size_info, user_data);
924         }
925         else
926         {
927                 pkgmgr_pkg_size_info_receive_cb callback = (pkgmgr_pkg_size_info_receive_cb)(pmc->new_event_cb);
928                 callback((pkgmgr_client *)pc, pkgid, size_info, user_data);
929         }
930
931 catch:
932
933         if(size_info){
934                 free(size_info);
935                 size_info = NULL;
936         }
937         return ret;
938 }
939
940 API pkgmgr_client *pkgmgr_client_new(client_type ctype)
941 {
942         pkgmgr_client_t *pc = NULL;
943         int ret = -1;
944
945         retvm_if(ctype == PC_BROADCAST, NULL, "broadcast type is not supported");
946         retvm_if(ctype != PC_REQUEST && ctype != PC_LISTENING, NULL, "ctype is not client_type");
947
948         /* Allocate memory for ADT:pkgmgr_client */
949         pc = calloc(1, sizeof(pkgmgr_client_t));
950         retvm_if(pc == NULL, NULL, "No memory");
951
952         /* Manage pc */
953         pc->ctype = ctype;
954         pc->status_type = PKGMGR_CLIENT_STATUS_ALL;
955         pc->tep_path = NULL;
956
957         if (pc->ctype == PC_REQUEST) {
958                 pc->info.request.cc = comm_client_new();
959                 trym_if(pc->info.request.cc == NULL, "client creation failed");
960
961                 ret = comm_client_set_status_callback(COMM_STATUS_BROADCAST_ALL, pc->info.request.cc, __operation_callback, pc);
962                 trym_if(ret < 0L, "comm_client_set_status_callback() failed - %d", ret);
963         } else if (pc->ctype == PC_LISTENING) {
964                 pc->info.listening.cc = comm_client_new();
965                 trym_if(pc->info.listening.cc == NULL, "client creation failed");
966
967                 ret = comm_client_set_status_callback(COMM_STATUS_BROADCAST_ALL, pc->info.listening.cc, __status_callback, pc);
968                 trym_if(ret < 0L, "comm_client_set_status_callback() failed - %d", ret);
969         }
970
971         return (pkgmgr_client *) pc;
972
973  catch:
974         if (pc)
975                 free(pc);
976         return NULL;
977 }
978
979 API int pkgmgr_client_free(pkgmgr_client *pc)
980 {
981         int ret = -1;
982         pkgmgr_client_t *mpc = (pkgmgr_client_t *) pc;
983         retvm_if(mpc == NULL, PKGMGR_R_EINVAL, "Invalid argument");
984
985         if (mpc->ctype == PC_REQUEST) {
986                 req_cb_info *tmp;
987                 req_cb_info *prev;
988                 for (tmp = mpc->info.request.rhead; tmp;) {
989                         prev = tmp;
990                         tmp = tmp->next;
991                         free(prev);
992                 }
993
994                 ret = comm_client_free(mpc->info.request.cc);
995                 tryvm_if(ret < 0, ret = PKGMGR_R_ERROR, "comm_client_free() failed");
996         } else if (mpc->ctype == PC_LISTENING) {
997                         listen_cb_info *tmp;
998                         listen_cb_info *prev;
999                         for (tmp = mpc->info.listening.lhead; tmp;) {
1000                                 prev = tmp;
1001                                 tmp = tmp->next;
1002                                 free(prev);
1003                         }
1004
1005                         ret = comm_client_free(mpc->info.listening.cc);
1006                         tryvm_if(ret < 0, ret = PKGMGR_R_ERROR, "comm_client_free() failed");
1007         } else if (mpc->ctype == PC_BROADCAST) {
1008                 ret = 0;
1009         } else {
1010                 ERR("Invalid client type\n");
1011                 return PKGMGR_R_EINVAL;
1012         }
1013
1014         if (mpc->tep_path) {
1015                 free(mpc->tep_path);
1016                 mpc->tep_path = NULL;
1017         }
1018
1019         if (mpc->tep_move) {
1020                 free(mpc->tep_move);
1021                 mpc->tep_move = NULL;
1022         }
1023
1024         free(mpc);
1025         mpc = NULL;
1026         return PKGMGR_R_OK;
1027
1028  catch:
1029         if (mpc) {
1030                 free(mpc);
1031                 mpc = NULL;
1032         }
1033         return PKGMGR_R_ERROR;
1034 }
1035
1036 static char *__get_type_from_path(const char *pkg_path)
1037 {
1038         int ret;
1039         char mimetype[255] = { '\0', };
1040         char extlist[256] = { '\0', };
1041         char *pkg_type;
1042
1043         ret = _get_mime_from_file(pkg_path, mimetype, sizeof(mimetype));
1044         if (ret) {
1045                 ERR("_get_mime_from_file() failed - error code[%d]\n", ret);
1046                 return NULL;
1047         }
1048
1049         ret = _get_mime_extension(mimetype, extlist, sizeof(extlist));
1050         if (ret) {
1051                 ERR("_get_mime_extension() failed - error code[%d]\n", ret);
1052                 return NULL;
1053         }
1054
1055         if (strlen(extlist) == 0)
1056                 return NULL;
1057
1058         if (strchr(extlist, ','))
1059                 extlist[strlen(extlist) - strlen(strchr(extlist, ','))] = '\0';
1060
1061         pkg_type = strchr(extlist, '.') + 1;
1062         return strdup(pkg_type);
1063 }
1064
1065 API int pkgmgr_client_set_tep_path(pkgmgr_client *pc, char *tep_path, char *tep_move)
1066 {
1067         retvm_if(pc == NULL, PKGMGR_R_EINVAL, "package manager client pc is NULL");
1068         retvm_if(tep_path == NULL, PKGMGR_R_EINVAL, "tep path is NULL");
1069         pkgmgr_client_t *mpc = (pkgmgr_client_t *) pc;
1070
1071         mpc->tep_path = strdup(tep_path);
1072         mpc->tep_move = strdup(tep_move);
1073
1074         return PKGMGR_R_OK;
1075 }
1076
1077 API int pkgmgr_client_usr_install(pkgmgr_client *pc, const char *pkg_type,
1078                 const char *descriptor_path, const char *pkg_path,
1079                 const char *optional_data, pkgmgr_mode mode,
1080                 pkgmgr_handler event_cb, void *data, uid_t uid)
1081 {
1082         GVariant *result;
1083         int ret = PKGMGR_R_ECOMM;
1084         char *req_key = NULL;
1085         GVariantBuilder *builder = NULL;
1086         GVariant *args = NULL;
1087         int req_id;
1088         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1089         char *pkgtype;
1090
1091         if (pc == NULL || pkg_path == NULL) {
1092                 ERR("invalid parameter");
1093                 return PKGMGR_R_EINVAL;
1094         }
1095
1096         if (mpc->ctype != PC_REQUEST) {
1097                 ERR("mpc->ctype is not PC_REQUEST");
1098                 return PKGMGR_R_EINVAL;
1099         }
1100
1101         if (access(pkg_path, F_OK) != 0) {
1102                 ERR("failed to access: %s", pkg_path);
1103                 return PKGMGR_R_EINVAL;
1104         }
1105
1106         if (mpc->tep_path != NULL && access(mpc->tep_path, F_OK) != 0) {
1107                 ERR("failed to access: %s", mpc->tep_path);
1108                 return PKGMGR_R_EINVAL;
1109         }
1110
1111         /* TODO: check pkg's type on server-side */
1112         if (pkg_type == NULL)
1113                 pkgtype = __get_type_from_path(pkg_path);
1114         else
1115                 pkgtype = strdup(pkg_type);
1116
1117         /* build arguments */
1118         builder = g_variant_builder_new(G_VARIANT_TYPE("as"));
1119         if (mpc->tep_path) {
1120                 g_variant_builder_add(builder, "s", "-e");
1121                 g_variant_builder_add(builder, "s", mpc->tep_path);
1122                 g_variant_builder_add(builder, "s", "-M");
1123                 g_variant_builder_add(builder, "s", mpc->tep_move);
1124         }
1125
1126         args = g_variant_new("as", builder);
1127         g_variant_builder_unref(builder);
1128
1129         result = comm_client_request(mpc->info.request.cc, "install",
1130                         g_variant_new("(uss@as)", uid, pkgtype, pkg_path, args));
1131
1132         if (result == NULL)
1133                 return PKGMGR_R_ECOMM;
1134         g_variant_get(result, "(i&s)", &ret, &req_key);
1135         if (req_key == NULL) {
1136                 g_variant_unref(result);
1137                 return PKGMGR_R_ECOMM;
1138         }
1139         if (ret != PKGMGR_R_OK) {
1140                 g_variant_unref(result);
1141                 return ret;
1142         }
1143
1144         req_id = _get_request_id();
1145         __add_op_cbinfo(mpc, req_id, req_key, event_cb, NULL, data);
1146
1147         g_variant_unref(result);
1148
1149         return req_id;
1150 }
1151
1152 API int pkgmgr_client_install(pkgmgr_client *pc, const char *pkg_type,
1153                 const char *descriptor_path, const char *pkg_path,
1154                 const char *optional_data, pkgmgr_mode mode,
1155                 pkgmgr_handler event_cb, void *data)
1156 {
1157         return pkgmgr_client_usr_install(pc, pkg_type, descriptor_path,
1158                         pkg_path, optional_data, mode, event_cb,data,
1159                         _getuid());
1160 }
1161
1162 API int pkgmgr_client_reinstall(pkgmgr_client *pc, const char *pkg_type,
1163                 const char *pkgid, const char *optional_data, pkgmgr_mode mode,
1164                 pkgmgr_handler event_cb, void *data)
1165 {
1166         return pkgmgr_client_usr_reinstall(pc, pkg_type, pkgid, optional_data,
1167                         mode, event_cb, data, _getuid());
1168 }
1169
1170 API int pkgmgr_client_usr_reinstall(pkgmgr_client * pc, const char *pkg_type,
1171                 const char *pkgid, const char *optional_data, pkgmgr_mode mode,
1172                 pkgmgr_handler event_cb, void *data, uid_t uid)
1173 {
1174         GVariant *result;
1175         int ret = PKGMGR_R_ECOMM;
1176         char *req_key = NULL;
1177         int req_id;
1178         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1179         char *pkgtype;
1180         pkgmgrinfo_pkginfo_h handle;
1181
1182         if (pc == NULL || pkgid == NULL) {
1183                 ERR("invalid parameter");
1184                 return PKGMGR_R_EINVAL;
1185         }
1186
1187         if (mpc->ctype != PC_REQUEST) {
1188                 ERR("mpc->ctype is not PC_REQUEST");
1189                 return PKGMGR_R_EINVAL;
1190         }
1191
1192         ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &handle);
1193         if (ret < 0)
1194                 return PKGMGR_R_EINVAL;
1195
1196         ret = pkgmgrinfo_pkginfo_get_type(handle, &pkgtype);
1197         if (ret < 0) {
1198                 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1199                 return PKGMGR_R_ERROR;
1200         }
1201
1202         result = comm_client_request(mpc->info.request.cc, "reinstall",
1203                         g_variant_new("(uss)", uid, pkgtype, pkgid));
1204         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1205         if (result == NULL)
1206                 return PKGMGR_R_ECOMM;
1207         g_variant_get(result, "(i&s)", &ret, &req_key);
1208         if (req_key == NULL) {
1209                 g_variant_unref(result);
1210                 return PKGMGR_R_ECOMM;
1211         }
1212         if (ret != PKGMGR_R_OK) {
1213                 g_variant_unref(result);
1214                 return ret;
1215         }
1216
1217         req_id = _get_request_id();
1218         __add_op_cbinfo(mpc, req_id, req_key, event_cb, NULL, data);
1219
1220         g_variant_unref(result);
1221
1222         return req_id;
1223 }
1224
1225 API int pkgmgr_client_uninstall(pkgmgr_client *pc, const char *pkg_type,
1226                 const char *pkgid, pkgmgr_mode mode, pkgmgr_handler event_cb,
1227                 void *data)
1228 {
1229         return pkgmgr_client_usr_uninstall(pc, pkg_type,pkgid, mode, event_cb,
1230                         data, _getuid());
1231 }
1232
1233 API int pkgmgr_client_usr_uninstall(pkgmgr_client *pc, const char *pkg_type,
1234                 const char *pkgid, pkgmgr_mode mode, pkgmgr_handler event_cb,
1235                 void *data, uid_t uid)
1236 {
1237         GVariant *result;
1238         int ret = PKGMGR_R_ECOMM;
1239         char *req_key = NULL;
1240         int req_id;
1241         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1242         char *pkgtype;
1243         pkgmgrinfo_pkginfo_h handle;
1244
1245         if (pc == NULL || pkgid == NULL) {
1246                 ERR("invalid parameter");
1247                 return PKGMGR_R_EINVAL;
1248         }
1249
1250         if (mpc->ctype != PC_REQUEST) {
1251                 ERR("mpc->ctype is not PC_REQUEST");
1252                 return PKGMGR_R_EINVAL;
1253         }
1254
1255         ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &handle);
1256         if (ret < 0)
1257                 return PKGMGR_R_EINVAL;
1258
1259         ret = pkgmgrinfo_pkginfo_get_type(handle, &pkgtype);
1260         if (ret < 0) {
1261                 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1262                 return PKGMGR_R_ERROR;
1263         }
1264
1265         /* TODO: check removable ? */
1266
1267         result = comm_client_request(mpc->info.request.cc, "uninstall",
1268                         g_variant_new("(uss)", uid, pkgtype, pkgid));
1269         if (result == NULL) {
1270                 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1271                 return PKGMGR_R_ECOMM;
1272         }
1273         g_variant_get(result, "(i&s)", &ret, &req_key);
1274         if (req_key == NULL) {
1275                 g_variant_unref(result);
1276                 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1277                 return PKGMGR_R_ECOMM;
1278         }
1279         if (ret != PKGMGR_R_OK) {
1280                 g_variant_unref(result);
1281                 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1282                 return ret;
1283         }
1284
1285         req_id = _get_request_id();
1286         __add_op_cbinfo(mpc, req_id, req_key, event_cb, NULL, data);
1287
1288         g_variant_unref(result);
1289         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1290
1291         return req_id;
1292 }
1293
1294 API int pkgmgr_client_move(pkgmgr_client *pc, const char *pkg_type,
1295                 const char *pkgid, pkgmgr_move_type move_type, pkgmgr_mode mode)
1296 {
1297         return pkgmgr_client_usr_move(pc, pkg_type, pkgid, move_type, mode,
1298                         _getuid());
1299 }
1300 API int pkgmgr_client_usr_move(pkgmgr_client *pc, const char *pkg_type,
1301                 const char *pkgid, pkgmgr_move_type move_type,
1302                 pkgmgr_mode mode, uid_t uid)
1303 {
1304         GVariant *result;
1305         int ret = PKGMGR_R_ECOMM;
1306         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1307
1308         if (pc == NULL || pkg_type == NULL || pkgid == NULL) {
1309                 ERR("invalid parameter");
1310                 return PKGMGR_R_EINVAL;
1311         }
1312
1313         if ((move_type < PM_MOVE_TO_INTERNAL) || (move_type > PM_MOVE_TO_SDCARD))
1314                 return PKGMGR_R_EINVAL;
1315
1316         if (mpc->ctype != PC_REQUEST) {
1317                 ERR("mpc->ctype is not PC_REQUEST");
1318                 return PKGMGR_R_EINVAL;
1319         }
1320
1321         result = comm_client_request(mpc->info.request.cc, "move",
1322                         g_variant_new("(uss)", uid, pkg_type, pkgid));
1323         if (result == NULL)
1324                 return PKGMGR_R_ECOMM;
1325         g_variant_get(result, "(i)", &ret);
1326         g_variant_unref(result);
1327
1328         return ret;
1329 }
1330
1331 API int pkgmgr_client_usr_activate(pkgmgr_client *pc, const char *pkg_type,
1332                 const char *pkgid, uid_t uid)
1333 {
1334         GVariant *result;
1335         int ret = PKGMGR_R_ECOMM;
1336         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1337
1338         if (pc == NULL || pkgid == NULL || pkg_type == NULL) {
1339                 ERR("invalid parameter");
1340                 return PKGMGR_R_EINVAL;
1341         }
1342
1343         result = comm_client_request(mpc->info.request.cc, "enable_pkg",
1344                         g_variant_new("(uss)", uid, pkg_type, pkgid));
1345         if (result == NULL)
1346                 return PKGMGR_R_ECOMM;
1347         g_variant_get(result, "(i)", &ret);
1348         g_variant_unref(result);
1349
1350         return ret;
1351 }
1352
1353 API int pkgmgr_client_activate(pkgmgr_client *pc, const char *pkg_type,
1354                 const char *pkgid)
1355 {
1356         return pkgmgr_client_usr_activate(pc, pkg_type, pkgid, _getuid());
1357 }
1358
1359 API int pkgmgr_client_usr_deactivate(pkgmgr_client *pc, const char *pkg_type,
1360                                  const char *pkgid, uid_t uid)
1361 {
1362         GVariant *result;
1363         int ret = PKGMGR_R_ECOMM;
1364         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1365
1366         if (pc == NULL || pkgid == NULL || pkg_type == NULL) {
1367                 ERR("invalid parameter");
1368                 return PKGMGR_R_EINVAL;
1369         }
1370
1371         result = comm_client_request(mpc->info.request.cc, "disable_pkg",
1372                         g_variant_new("(uss)", uid, pkg_type, pkgid));
1373         if (result == NULL)
1374                 return PKGMGR_R_ECOMM;
1375         g_variant_get(result, "(i)", &ret);
1376         g_variant_unref(result);
1377
1378         return ret;
1379 }
1380
1381 API int pkgmgr_client_deactivate(pkgmgr_client *pc, const char *pkg_type,
1382                                  const char *pkgid)
1383 {
1384         return pkgmgr_client_usr_deactivate(pc, pkg_type, pkgid, _getuid());
1385 }
1386
1387 /* TODO: deprecate? */
1388 API int pkgmgr_client_usr_activate_appv(pkgmgr_client *pc, const char *appid,
1389                 char *const argv[], uid_t uid)
1390 {
1391         return pkgmgr_client_usr_activate_app(pc, appid, NULL, uid);
1392 }
1393
1394 API int pkgmgr_client_activate_appv(pkgmgr_client *pc, const char *appid,
1395                 char *const argv[])
1396 {
1397         return pkgmgr_client_usr_activate_app(pc, appid, NULL, _getuid());
1398 }
1399
1400 API int pkgmgr_client_usr_activate_app(pkgmgr_client *pc, const char *appid,
1401                 pkgmgr_app_handler app_event_cb, uid_t uid)
1402 {
1403         GVariant *result;
1404         int ret = PKGMGR_R_ECOMM;
1405         int req_id;
1406         char *req_key = NULL;
1407         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1408
1409         if (pc == NULL || appid == NULL) {
1410                 ERR("invalid parameter");
1411                 return PKGMGR_R_EINVAL;
1412         }
1413
1414         if (__change_op_cb_for_enable_disable(mpc, false) < 0) {
1415                 ERR("__change_op_cb_for_enable_disable failed");
1416                 return PKGMGR_R_ESYSTEM;
1417         }
1418
1419         result = comm_client_request(mpc->info.request.cc, "enable_app",
1420                         g_variant_new("(us)", uid, appid));
1421         if (result == NULL)
1422                 return PKGMGR_R_ECOMM;
1423         g_variant_get(result, "(i&s)", &ret, &req_key);
1424         if (req_key == NULL) {
1425                 g_variant_unref(result);
1426                 return PKGMGR_R_ECOMM;
1427         }
1428         if (ret != PKGMGR_R_OK) {
1429                 g_variant_unref(result);
1430                 return ret;
1431         }
1432
1433         req_id = _get_request_id();
1434         __add_op_app_cbinfo(pc, req_id, req_key, app_event_cb, NULL);
1435         g_variant_unref(result);
1436         return ret;
1437 }
1438
1439 API int pkgmgr_client_activate_app(pkgmgr_client * pc, const char *appid, pkgmgr_app_handler app_event_cb)
1440 {
1441         return pkgmgr_client_usr_activate_app(pc, appid, app_event_cb, _getuid());
1442 }
1443
1444 API int pkgmgr_client_activate_global_app_for_uid(pkgmgr_client *pc,
1445                                  const char *appid, pkgmgr_app_handler app_event_cb, uid_t uid)
1446 {
1447         GVariant *result;
1448         int ret = PKGMGR_R_ECOMM;
1449         int req_id;
1450         char *req_key = NULL;
1451         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1452
1453         if (pc == NULL || appid == NULL) {
1454                 ERR("invalid parameter");
1455                 return PKGMGR_R_EINVAL;
1456         }
1457
1458         if (__change_op_cb_for_enable_disable(mpc, false) < 0) {
1459                 ERR("__change_op_cb_for_enable_disable failed");
1460                 return PKGMGR_R_ESYSTEM;
1461         }
1462
1463         result = comm_client_request(mpc->info.request.cc, "enable_global_app_for_uid",
1464                         g_variant_new("(us)", uid, appid));
1465         if (result == NULL)
1466                 return PKGMGR_R_ECOMM;
1467         g_variant_get(result, "(i&s)", &ret, &req_key);
1468         if (req_key == NULL) {
1469                 g_variant_unref(result);
1470                 return PKGMGR_R_ECOMM;
1471         }
1472         if (ret != PKGMGR_R_OK) {
1473                 g_variant_unref(result);
1474                 return ret;
1475         }
1476
1477         req_id = _get_request_id();
1478         __add_op_app_cbinfo(pc, req_id, req_key, app_event_cb, NULL);
1479
1480         return ret;
1481 }
1482
1483 API int pkgmgr_client_usr_deactivate_app(pkgmgr_client *pc, const char *appid,
1484                 pkgmgr_app_handler app_event_cb, uid_t uid)
1485 {
1486         GVariant *result;
1487         int ret = PKGMGR_R_ECOMM;
1488         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1489         int req_id;
1490         char *req_key = NULL;
1491
1492         if (pc == NULL || appid == NULL) {
1493                 ERR("invalid parameter");
1494                 return PKGMGR_R_EINVAL;
1495         }
1496
1497         /* FIXME */
1498         if (__change_op_cb_for_enable_disable(mpc, true) < 0) {
1499                 ERR("__change_op_cb_for_enable_disable failed");
1500                 return PKGMGR_R_ESYSTEM;
1501         }
1502
1503         result = comm_client_request(mpc->info.request.cc, "disable_app",
1504                         g_variant_new("(us)", uid, appid));
1505
1506         if (result == NULL)
1507                 return PKGMGR_R_ECOMM;
1508         g_variant_get(result, "(i&s)", &ret, &req_key);
1509         if (req_key == NULL) {
1510                 g_variant_unref(result);
1511                 return PKGMGR_R_ECOMM;
1512         }
1513         if (ret != PKGMGR_R_OK) {
1514                 g_variant_unref(result);
1515                 return ret;
1516         }
1517
1518         req_id = _get_request_id();
1519         __add_op_app_cbinfo(pc, req_id, req_key, app_event_cb, NULL);
1520
1521         g_variant_unref(result);
1522         return ret;
1523 }
1524
1525 API int pkgmgr_client_deactivate_app(pkgmgr_client *pc, const char *appid, pkgmgr_app_handler app_event_cb)
1526 {
1527         return pkgmgr_client_usr_deactivate_app(pc, appid, app_event_cb, _getuid());
1528 }
1529
1530 API int pkgmgr_client_deactivate_global_app_for_uid(pkgmgr_client *pc,
1531                                  const char *appid, pkgmgr_app_handler app_event_cb, uid_t uid)
1532 {
1533         GVariant *result;
1534         int ret = PKGMGR_R_ECOMM;
1535         int req_id;
1536         char *req_key = NULL;
1537         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1538
1539         if (pc == NULL || appid == NULL) {
1540                 ERR("invalid parameter");
1541                 return PKGMGR_R_EINVAL;
1542         }
1543
1544         if (__change_op_cb_for_enable_disable(mpc, true) < 0) {
1545                 ERR("__change_op_cb_for_enable_disable failed");
1546                 return PKGMGR_R_ESYSTEM;
1547         }
1548
1549         result = comm_client_request(mpc->info.request.cc, "disable_global_app_for_uid",
1550                         g_variant_new("(us)", uid, appid));
1551
1552         if (result == NULL)
1553                 return PKGMGR_R_ECOMM;
1554         g_variant_get(result, "(i&s)", &ret, &req_key);
1555         if (req_key == NULL) {
1556                 g_variant_unref(result);
1557                 return PKGMGR_R_ECOMM;
1558         }
1559         if (ret != PKGMGR_R_OK) {
1560                 g_variant_unref(result);
1561                 return ret;
1562         }
1563
1564         req_id = _get_request_id();
1565         __add_op_app_cbinfo(pc, req_id, req_key, app_event_cb, NULL);
1566         return ret;
1567 }
1568
1569 API int pkgmgr_client_usr_clear_user_data(pkgmgr_client *pc,
1570                 const char *pkg_type, const char *appid, pkgmgr_mode mode,
1571                 uid_t uid)
1572 {
1573         GVariant *result;
1574         int ret = PKGMGR_R_ECOMM;
1575         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1576
1577         if (pc == NULL || pkg_type == NULL || appid == NULL) {
1578                 ERR("invalid parameter");
1579                 return PKGMGR_R_EINVAL;
1580         }
1581
1582         if (mpc->ctype != PC_REQUEST) {
1583                 ERR("mpc->ctype is not PC_REQUEST");
1584                 return PKGMGR_R_EINVAL;
1585         }
1586
1587         result = comm_client_request(mpc->info.request.cc, "cleardata",
1588                         g_variant_new("(uss)", uid, pkg_type, appid));
1589         if (result == NULL)
1590                 return PKGMGR_R_ECOMM;
1591
1592         g_variant_get(result, "(i)", &ret);
1593         g_variant_unref(result);
1594
1595         return ret;
1596 }
1597
1598 API int pkgmgr_client_clear_user_data(pkgmgr_client *pc, const char *pkg_type,
1599                 const char *appid, pkgmgr_mode mode)
1600 {
1601         return pkgmgr_client_usr_clear_user_data(pc, pkg_type, appid, mode,
1602                         _getuid());
1603 }
1604
1605 API int pkgmgr_client_set_status_type(pkgmgr_client *pc, int status_type)
1606 {
1607         int ret = -1;
1608
1609         retvm_if(pc == NULL, PKGMGR_R_EINVAL, "package manager client pc is NULL");
1610         retvm_if(status_type == PKGMGR_CLIENT_STATUS_ALL, PKGMGR_R_OK, "status_type is PKGMGR_CLIENT_STATUS_ALL");
1611         pkgmgr_client_t *mpc = (pkgmgr_client_t *) pc;
1612
1613         /*  free listening head */
1614         listen_cb_info *tmp = NULL;
1615         listen_cb_info *prev = NULL;
1616         for (tmp = mpc->info.listening.lhead; tmp;) {
1617                 prev = tmp;
1618                 tmp = tmp->next;
1619                 free(prev);
1620         }
1621
1622         /* free dbus connection */
1623         ret = comm_client_free(mpc->info.listening.cc);
1624         retvm_if(ret < 0, PKGMGR_R_ERROR, "comm_client_free() failed - %d", ret);
1625
1626         /* Manage pc for seperated event */
1627         mpc->ctype = PC_LISTENING;
1628         mpc->status_type = status_type;
1629
1630         mpc->info.listening.cc = comm_client_new();
1631         retvm_if(mpc->info.listening.cc == NULL, PKGMGR_R_EINVAL, "client creation failed");
1632
1633         if ((mpc->status_type & PKGMGR_CLIENT_STATUS_INSTALL) == PKGMGR_CLIENT_STATUS_INSTALL) {
1634                 ret = comm_client_set_status_callback(COMM_STATUS_BROADCAST_INSTALL, mpc->info.listening.cc, __status_callback, pc);
1635                 retvm_if(ret < 0, PKGMGR_R_ECOMM, "PKGMGR_CLIENT_STATUS_INSTALL failed - %d", ret);
1636         }
1637
1638         if ((mpc->status_type & PKGMGR_CLIENT_STATUS_UNINSTALL) == PKGMGR_CLIENT_STATUS_UNINSTALL) {
1639                 ret = comm_client_set_status_callback(COMM_STATUS_BROADCAST_UNINSTALL, mpc->info.listening.cc, __status_callback, pc);
1640                 retvm_if(ret < 0, PKGMGR_R_ECOMM, "COMM_STATUS_BROADCAST_UNINSTALL failed - %d", ret);
1641         }
1642
1643         if ((mpc->status_type & PKGMGR_CLIENT_STATUS_MOVE) == PKGMGR_CLIENT_STATUS_MOVE) {
1644                 ret = comm_client_set_status_callback(COMM_STATUS_BROADCAST_MOVE, mpc->info.listening.cc, __status_callback, pc);
1645                 retvm_if(ret < 0, PKGMGR_R_ECOMM, "COMM_STATUS_BROADCAST_MOVE failed - %d", ret);
1646         }
1647
1648         if ((mpc->status_type & PKGMGR_CLIENT_STATUS_INSTALL_PROGRESS) == PKGMGR_CLIENT_STATUS_INSTALL_PROGRESS) {
1649                 ret = comm_client_set_status_callback(COMM_STATUS_BROADCAST_INSTALL_PROGRESS, mpc->info.listening.cc, __status_callback, pc);
1650                 retvm_if(ret < 0, PKGMGR_R_ECOMM, "COMM_STATUS_BROADCAST_INSTALL_PROGRESS failed - %d", ret);
1651         }
1652
1653    if ((mpc->status_type & PKGMGR_CLIENT_STATUS_UPGRADE) == PKGMGR_CLIENT_STATUS_UPGRADE) {
1654                 ret = comm_client_set_status_callback(COMM_STATUS_BROADCAST_UPGRADE, mpc->info.listening.cc, __status_callback, pc);
1655                 retvm_if(ret < 0, PKGMGR_R_ECOMM, "COMM_STATUS_BROADCAST_UPGRADE failed - %d", ret);
1656         }
1657
1658    if ((mpc->status_type & PKGMGR_CLIENT_STATUS_ENABLE_APP) == PKGMGR_CLIENT_STATUS_ENABLE_APP) {
1659                 ret = comm_client_set_status_callback(COMM_STATUS_BROADCAST_ENABLE_APP, mpc->info.listening.cc, __status_callback, pc);
1660                 retvm_if(ret < 0, PKGMGR_R_ECOMM, "COMM_STATUS_BROADCAST_ENABLE_APP failed - %d", ret);
1661         }
1662
1663    if ((mpc->status_type & PKGMGR_CLIENT_STATUS_DISABLE_APP) == PKGMGR_CLIENT_STATUS_DISABLE_APP) {
1664                 ret = comm_client_set_status_callback(COMM_STATUS_BROADCAST_DISABLE_APP, mpc->info.listening.cc, __status_callback, pc);
1665                 retvm_if(ret < 0, PKGMGR_R_ECOMM, "COMM_STATUS_BROADCAST_DISABLE_APP failed - %d", ret);
1666         }
1667
1668    return PKGMGR_R_OK;
1669 }
1670
1671 API int pkgmgr_client_listen_status(pkgmgr_client *pc, pkgmgr_handler event_cb,
1672                                     void *data)
1673 {
1674         int req_id;
1675         /* Check for NULL value of pc */
1676         retvm_if(pc == NULL, PKGMGR_R_EINVAL, "package manager client pc is NULL");
1677         pkgmgr_client_t *mpc = (pkgmgr_client_t *) pc;
1678
1679         /* 0. check input */
1680         retvm_if(mpc->ctype != PC_LISTENING, PKGMGR_R_EINVAL, "ctype is not PC_LISTENING");
1681         retvm_if(event_cb == NULL, PKGMGR_R_EINVAL, "event_cb is NULL");
1682
1683         /* 1. get id */
1684         req_id = _get_request_id();
1685
1686         /* 2. add callback info to pkgmgr_client */
1687         __add_stat_cbinfo(mpc, req_id, event_cb, data);
1688         return req_id;
1689 }
1690
1691 API int pkgmgr_client_listen_app_status(pkgmgr_client *pc, pkgmgr_app_handler event_cb,
1692                                     void *data)
1693 {
1694         int req_id;
1695         /* Check for NULL value of pc */
1696         retvm_if(pc == NULL, PKGMGR_R_EINVAL, "package manager client pc is NULL");
1697         pkgmgr_client_t *mpc = (pkgmgr_client_t *) pc;
1698
1699         /* 0. check input */
1700         retvm_if(mpc->ctype != PC_LISTENING, PKGMGR_R_EINVAL, "ctype is not PC_LISTENING");
1701         retvm_if(event_cb == NULL, PKGMGR_R_EINVAL, "event_cb is NULL");
1702
1703         /* 1. get id */
1704         req_id = _get_request_id();
1705
1706         /* 2. add app callback info to pkgmgr_client */
1707         __add_app_stat_cbinfo(mpc, req_id, event_cb, data);
1708         return req_id;
1709 }
1710
1711 API int pkgmgr_client_remove_listen_status(pkgmgr_client *pc)
1712 {
1713         int ret = -1;
1714
1715         retvm_if(pc == NULL, PKGMGR_R_EINVAL, "package manager client pc is NULL");
1716         pkgmgr_client_t *mpc = (pkgmgr_client_t *) pc;
1717
1718         ret = __remove_stat_cbinfo(mpc);
1719         if (ret != 0) {
1720                 ERR("failed to remove status callback");
1721                 return PKGMGR_R_ERROR;
1722         }
1723
1724         return PKGMGR_R_OK;
1725 }
1726
1727 API int pkgmgr_client_broadcast_status(pkgmgr_client *pc, const char *pkg_type,
1728                                        const char *pkgid, const char *key,
1729                                        const char *val)
1730 {
1731         /* client cannot broadcast signal */
1732         return PKGMGR_R_OK;
1733 }
1734
1735 API int pkgmgr_client_request_service(pkgmgr_request_service_type service_type, int service_mode,
1736                                   pkgmgr_client * pc, const char *pkg_type, const char *pkgid,
1737                               const char *custom_info, pkgmgr_handler event_cb, void *data)
1738 {
1739         return pkgmgr_client_usr_request_service(service_type, service_mode, pc, pkg_type, pkgid, _getuid(), custom_info, event_cb, data);
1740 }
1741
1742 API int pkgmgr_client_usr_request_service(pkgmgr_request_service_type service_type, int service_mode,
1743                                   pkgmgr_client * pc, const char *pkg_type, const char *pkgid, uid_t uid,
1744                               const char *custom_info, pkgmgr_handler event_cb, void *data)
1745 {
1746         int ret =0;
1747
1748         /* Check for NULL value of service type */
1749         retvm_if(service_type > PM_REQUEST_MAX, PKGMGR_R_EINVAL, "service type is not defined\n");
1750         retvm_if(service_type < 0, PKGMGR_R_EINVAL, "service type is error\n");
1751
1752         switch (service_type) {
1753         case PM_REQUEST_CSC:
1754                 tryvm_if(custom_info == NULL, ret = PKGMGR_R_EINVAL, "custom_info is NULL\n");
1755                 tryvm_if(strlen(custom_info) >= PKG_STRING_LEN_MAX, ret = PKGMGR_R_EINVAL, "custom_info over PKG_STRING_LEN_MAX");
1756                 tryvm_if(data == NULL, ret = PKGMGR_R_EINVAL, "data is NULL\n");
1757
1758                 ret = __csc_process(custom_info, (char *)data);
1759                 if (ret < 0)
1760                         ERR("__csc_process fail \n");
1761                 else
1762                         ret = PKGMGR_R_OK;
1763
1764                 break;
1765
1766         case PM_REQUEST_MOVE:
1767                 tryvm_if(pkgid == NULL, ret = PKGMGR_R_EINVAL, "pkgid is NULL\n");
1768                 tryvm_if(pc == NULL, ret = PKGMGR_R_EINVAL, "pc is NULL\n");
1769                 tryvm_if((service_mode < PM_MOVE_TO_INTERNAL) || (service_mode > PM_MOVE_TO_SDCARD), ret = PKGMGR_R_EINVAL, "service_mode is wrong\n");
1770
1771                 ret = __move_pkg_process(pc, pkgid, pkg_type, uid, (pkgmgr_move_type)service_mode, event_cb, data);
1772                 break;
1773
1774         case PM_REQUEST_GET_SIZE:
1775                 tryvm_if(pkgid == NULL, ret = PKGMGR_R_EINVAL, "pkgid is NULL\n");
1776                 tryvm_if(pc == NULL, ret = PKGMGR_R_EINVAL, "pc is NULL\n");
1777                 tryvm_if((service_mode < PM_GET_TOTAL_SIZE) || (service_mode >= PM_GET_MAX), ret = PKGMGR_R_EINVAL, "service_mode is wrong\n");
1778
1779                 ret = __get_size_process(pc, pkgid, uid, (pkgmgr_getsize_type)service_mode, event_cb, data);
1780                 break;
1781
1782         case PM_REQUEST_KILL_APP:
1783         case PM_REQUEST_CHECK_APP:
1784                 tryvm_if(pkgid == NULL, ret = PKGMGR_R_EINVAL, "pkgid is NULL\n");
1785                 tryvm_if(pc == NULL, ret = PKGMGR_R_EINVAL, "pc is NULL\n");
1786
1787                 ret = __check_app_process(service_type, pc, pkgid, uid, data);
1788                 if (ret < 0)
1789                         ERR("__check_app_process fail \n");
1790                 else
1791                         ret = PKGMGR_R_OK;
1792
1793                 break;
1794
1795         default:
1796                 ERR("Wrong Request\n");
1797                 ret = -1;
1798                 break;
1799         }
1800
1801 catch:
1802
1803         return ret;
1804 }
1805
1806
1807 API int pkgmgr_client_usr_request_size_info(uid_t uid)
1808 {
1809         int ret = 0;
1810         pkgmgr_client *pc = NULL;
1811
1812         pc = pkgmgr_client_new(PC_REQUEST);
1813         retvm_if(pc == NULL, PKGMGR_R_EINVAL, "request pc is null\n");
1814
1815         ret = __request_size_info(pc, uid);
1816         if (ret < 0) {
1817                 ERR("__request_size_info fail \n");
1818         }
1819
1820         pkgmgr_client_free(pc);
1821         return ret;
1822 }
1823
1824 API int pkgmgr_client_request_size_info(void) // get all package size (data, total)
1825 {
1826         return pkgmgr_client_usr_request_size_info(_getuid());
1827 }
1828
1829 API int pkgmgr_client_usr_clear_cache_dir(const char *pkgid, uid_t uid)
1830 {
1831         GVariant *result;
1832         int ret = PKGMGR_R_ECOMM;
1833         pkgmgr_client_t *pc;
1834
1835         if (pkgid == NULL) {
1836                 ERR("invalid parameter");
1837                 return PKGMGR_R_EINVAL;
1838         }
1839
1840         pc = pkgmgr_client_new(PC_REQUEST);
1841         if (pc == NULL) {
1842                 ERR("out of memory");
1843                 return PKGMGR_R_ESYSTEM;
1844         }
1845
1846         result = comm_client_request(pc->info.request.cc, "clearcache",
1847                         g_variant_new("(us)", uid, pkgid));
1848         if (result == NULL)
1849                 return PKGMGR_R_ECOMM;
1850         g_variant_get(result, "(i)", &ret);
1851         g_variant_unref(result);
1852
1853         return ret;
1854 }
1855
1856 API int pkgmgr_client_clear_cache_dir(const char *pkgid)
1857 {
1858         return pkgmgr_client_usr_clear_cache_dir(pkgid, _getuid());
1859 }
1860
1861 API int pkgmgr_client_clear_usr_all_cache_dir(uid_t uid)
1862 {
1863         return pkgmgr_client_usr_clear_cache_dir(PKG_CLEAR_ALL_CACHE, uid);
1864 }
1865
1866 API int pkgmgr_client_clear_all_cache_dir(void)
1867 {
1868         return pkgmgr_client_usr_clear_cache_dir(PKG_CLEAR_ALL_CACHE, _getuid());
1869 }
1870
1871 API int pkgmgr_client_get_size(pkgmgr_client * pc, const char *pkgid,
1872                 pkgmgr_getsize_type get_type, pkgmgr_handler event_cb,
1873                 void *data)
1874 {
1875         return pkgmgr_client_usr_get_size(pc, pkgid, get_type, event_cb, data,
1876                         _getuid());
1877 }
1878
1879 API int pkgmgr_client_usr_get_size(pkgmgr_client * pc, const char *pkgid,
1880                 pkgmgr_getsize_type get_type, pkgmgr_handler event_cb,
1881                 void *data, uid_t uid)
1882 {
1883         GVariant *result;
1884         int ret = PKGMGR_R_ECOMM;
1885         char *req_key = NULL;
1886         int req_id;
1887         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1888
1889         if (pc == NULL || pkgid == NULL || event_cb == NULL) {
1890                 ERR("invalid parameter");
1891                 return PKGMGR_R_EINVAL;
1892         }
1893
1894         if (mpc->ctype != PC_REQUEST) {
1895                 ERR("mpc->ctype is not PC_REQUEST");
1896                 return PKGMGR_R_EINVAL;
1897         }
1898
1899         /* FIXME */
1900         if (strcmp(pkgid, PKG_SIZE_INFO_TOTAL) == 0)
1901                 get_type = PM_GET_TOTAL_PKG_SIZE_INFO;
1902         else
1903                 get_type = PM_GET_PKG_SIZE_INFO;
1904         result = comm_client_request(mpc->info.request.cc, "getsize",
1905                         g_variant_new("(usi)", uid, pkgid, get_type));
1906         if (result == NULL)
1907                 return PKGMGR_R_ECOMM;
1908
1909         g_variant_get(result, "(i&s)", &ret, &req_key);
1910         if (req_key == NULL) {
1911                 g_variant_unref(result);
1912                 return PKGMGR_R_ECOMM;
1913         }
1914         if (ret != PKGMGR_R_OK) {
1915                 g_variant_unref(result);
1916                 return ret;
1917         }
1918
1919         req_id = _get_request_id();
1920         __add_op_cbinfo(mpc, req_id, req_key, event_cb, NULL, data);
1921
1922         g_variant_unref(result);
1923
1924         return PKGMGR_R_OK;
1925 }
1926
1927 API int pkgmgr_client_usr_get_package_size_info(pkgmgr_client *pc,
1928                 const char *pkgid, pkgmgr_pkg_size_info_receive_cb event_cb,
1929                 void *user_data, uid_t uid)
1930 {
1931         GVariant *result;
1932         int ret = PKGMGR_R_ECOMM;
1933         char *req_key = NULL;
1934         int req_id;
1935         int get_type;
1936         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1937
1938         if (pc == NULL || pkgid == NULL || event_cb == NULL) {
1939                 ERR("invalid parameter");
1940                 return PKGMGR_R_EINVAL;
1941         }
1942
1943         if (mpc->ctype != PC_REQUEST) {
1944                 ERR("mpc->ctype is not PC_REQUEST");
1945                 return PKGMGR_R_EINVAL;
1946         }
1947
1948         /* FIXME */
1949         if (__change_op_cb_for_getsize(mpc) < 0) {
1950                 ERR("__change_op_cb_for_getsize failed");
1951                 return PKGMGR_R_ESYSTEM;
1952         }
1953
1954         if (strcmp(pkgid, PKG_SIZE_INFO_TOTAL) == 0)
1955                 get_type = PM_GET_TOTAL_PKG_SIZE_INFO;
1956         else
1957                 get_type = PM_GET_PKG_SIZE_INFO;
1958         result = comm_client_request(mpc->info.request.cc, "getsize",
1959                         g_variant_new("(usi)", uid, pkgid, get_type));
1960         if (result == NULL)
1961                 return PKGMGR_R_ECOMM;
1962
1963         g_variant_get(result, "(i&s)", &ret, &req_key);
1964         if (req_key == NULL) {
1965                 g_variant_unref(result);
1966                 return PKGMGR_R_ECOMM;
1967         }
1968         if (ret != PKGMGR_R_OK) {
1969                 g_variant_unref(result);
1970                 return ret;
1971         }
1972
1973         req_id = _get_request_id();
1974         __add_op_cbinfo(mpc, req_id, req_key, __get_pkg_size_info_cb, event_cb,
1975                         user_data);
1976
1977         g_variant_unref(result);
1978
1979         return PKGMGR_R_OK;
1980 }
1981
1982 API int pkgmgr_client_get_package_size_info(pkgmgr_client *pc, const char *pkgid, pkgmgr_pkg_size_info_receive_cb event_cb, void *user_data)
1983 {
1984         return pkgmgr_client_usr_get_package_size_info(pc, pkgid, event_cb, user_data, _getuid());
1985 }
1986
1987 API int pkgmgr_client_usr_get_total_package_size_info(pkgmgr_client *pc, pkgmgr_total_pkg_size_info_receive_cb event_cb, void *user_data, uid_t uid)
1988 {       // total package size info
1989         return pkgmgr_client_usr_get_package_size_info(pc, PKG_SIZE_INFO_TOTAL, (pkgmgr_pkg_size_info_receive_cb)event_cb, user_data, uid);
1990 }
1991
1992 API int pkgmgr_client_get_total_package_size_info(pkgmgr_client *pc, pkgmgr_total_pkg_size_info_receive_cb event_cb, void *user_data)
1993 {
1994         return pkgmgr_client_usr_get_package_size_info(pc, PKG_SIZE_INFO_TOTAL, (pkgmgr_pkg_size_info_receive_cb)event_cb, user_data, _getuid());
1995 }
1996
1997 API int pkgmgr_client_generate_license_request(pkgmgr_client *pc,
1998                 const char *resp_data, char **req_data, char **license_url)
1999 {
2000         GVariant *result;
2001         int ret;
2002         char *data;
2003         char *url;
2004         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
2005
2006         if (pc == NULL || resp_data == NULL || req_data == NULL ||
2007                         license_url == NULL) {
2008                 ERR("invalid parameter");
2009                 return PKGMGR_R_EINVAL;
2010         }
2011
2012         if (mpc->ctype != PC_REQUEST) {
2013                 ERR("mpc->ctype is not PC_REQUEST");
2014                 return PKGMGR_R_EINVAL;
2015         }
2016
2017         result = comm_client_request(mpc->info.request.cc,
2018                         "generate_license_request",
2019                         g_variant_new("(s)", resp_data));
2020         if (result == NULL)
2021                 return PKGMGR_R_ECOMM;
2022
2023         g_variant_get(result, "(i&s&s)", &ret, &data, &url);
2024         if (ret != PKGMGR_R_OK) {
2025                 ERR("generate_license_request failed: %d", ret);
2026                 g_variant_unref(result);
2027                 return ret;
2028         }
2029
2030         *req_data = strdup(data);
2031         *license_url = strdup(url);
2032
2033         g_variant_unref(result);
2034
2035         return PKGMGR_R_OK;
2036 }
2037
2038 API int pkgmgr_client_register_license(pkgmgr_client *pc, const char *resp_data)
2039 {
2040         GVariant *result;
2041         int ret;
2042         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
2043
2044         if (pc == NULL || resp_data == NULL) {
2045                 ERR("invalid parameter");
2046                 return PKGMGR_R_EINVAL;
2047         }
2048
2049         if (mpc->ctype != PC_REQUEST) {
2050                 ERR("mpc->ctype is not PC_REQUEST");
2051                 return PKGMGR_R_EINVAL;
2052         }
2053
2054         result = comm_client_request(mpc->info.request.cc,
2055                         "register_license", g_variant_new("(s)", resp_data));
2056         if (result == NULL)
2057                 return PKGMGR_R_ECOMM;
2058
2059         g_variant_get(result, "(i)", &ret);
2060         g_variant_unref(result);
2061         if (ret != PKGMGR_R_OK) {
2062                 ERR("register license failed: %d", ret);
2063                 return ret;
2064         }
2065
2066         return PKGMGR_R_OK;
2067 }
2068
2069 API int pkgmgr_client_decrypt_package(pkgmgr_client *pc,
2070                 const char *drm_file_path, const char *decrypted_file_path)
2071 {
2072         GVariant *result;
2073         int ret;
2074         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
2075
2076         if (pc == NULL || drm_file_path == NULL ||
2077                         decrypted_file_path == NULL) {
2078                 ERR("invalid parameter");
2079                 return PKGMGR_R_EINVAL;
2080         }
2081
2082         if (mpc->ctype != PC_REQUEST) {
2083                 ERR("mpc->ctype is not PC_REQUEST");
2084                 return PKGMGR_R_EINVAL;
2085         }
2086
2087         result = comm_client_request(mpc->info.request.cc,
2088                         "decrypt_package", g_variant_new("(ss)",
2089                                 drm_file_path, decrypted_file_path));
2090         if (result == NULL)
2091                 return PKGMGR_R_ECOMM;
2092
2093         g_variant_get(result, "(i)", &ret);
2094         g_variant_unref(result);
2095         if (ret != PKGMGR_R_OK) {
2096                 ERR("decrypt_package failed: %d", ret);
2097                 return ret;
2098         }
2099
2100         return PKGMGR_R_OK;
2101 }
2102
2103 API int pkgmgr_client_usr_add_blacklist(pkgmgr_client *pc, const char *pkgid,
2104                 uid_t uid)
2105 {
2106         GVariant *result;
2107         int ret = PKGMGR_R_ECOMM;
2108         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
2109
2110         if (pc == NULL || pkgid == NULL) {
2111                 ERR("invalid parameter");
2112                 return PKGMGR_R_EINVAL;
2113         }
2114
2115         result = comm_client_request(mpc->info.request.cc, "add_blacklist",
2116                         g_variant_new("(us)", uid, pkgid));
2117         if (result == NULL)
2118                 return PKGMGR_R_ECOMM;
2119         g_variant_get(result, "(i)", &ret);
2120         g_variant_unref(result);
2121
2122         return ret;
2123 }
2124
2125 API int pkgmgr_client_add_blacklist(pkgmgr_client *pc, const char *pkgid)
2126 {
2127         return pkgmgr_client_usr_add_blacklist(pc, pkgid, _getuid());
2128 }
2129
2130 API int pkgmgr_client_usr_remove_blacklist(pkgmgr_client *pc,
2131                 const char *pkgid, uid_t uid)
2132 {
2133         GVariant *result;
2134         int ret = PKGMGR_R_ECOMM;
2135         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
2136
2137         if (pc == NULL || pkgid == NULL) {
2138                 ERR("invalid parameter");
2139                 return PKGMGR_R_EINVAL;
2140         }
2141
2142         result = comm_client_request(mpc->info.request.cc, "remove_blacklist",
2143                         g_variant_new("(us)", uid, pkgid));
2144         if (result == NULL)
2145                 return PKGMGR_R_ECOMM;
2146         g_variant_get(result, "(i)", &ret);
2147         g_variant_unref(result);
2148
2149         return ret;
2150 }
2151
2152 API int pkgmgr_client_remove_blacklist(pkgmgr_client *pc,
2153                 const char *pkgid)
2154 {
2155         return pkgmgr_client_usr_remove_blacklist(pc, pkgid, _getuid());
2156 }
2157
2158 API int pkgmgr_client_usr_check_blacklist(pkgmgr_client *pc, const char *pkgid,
2159                 bool *blacklist, uid_t uid)
2160 {
2161         GVariant *result;
2162         int ret = PKGMGR_R_ECOMM;
2163         gint b;
2164         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
2165
2166         if (pc == NULL || pkgid == NULL) {
2167                 ERR("invalid parameter");
2168                 return PKGMGR_R_EINVAL;
2169         }
2170
2171         result = comm_client_request(mpc->info.request.cc, "check_blacklist",
2172                         g_variant_new("(us)", uid, pkgid));
2173         if (result == NULL)
2174                 return PKGMGR_R_ECOMM;
2175         g_variant_get(result, "(ii)", &b, &ret);
2176         g_variant_unref(result);
2177
2178         if (ret != PKGMGR_R_OK)
2179                 return ret;
2180
2181         if (b)
2182                 *blacklist = true;
2183         else
2184                 *blacklist = false;
2185
2186         return PKGMGR_R_OK;
2187 }
2188
2189 API int pkgmgr_client_check_blacklist(pkgmgr_client *pc, const char *pkgid,
2190                 bool *blacklist)
2191 {
2192         return pkgmgr_client_usr_check_blacklist(pc, pkgid, blacklist,
2193                         _getuid());
2194 }