Fix install 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
53 static int _get_request_id()
54 {
55         static int internal_req_id = 1;
56
57         return internal_req_id++;
58 }
59
60 typedef struct _req_cb_info {
61         int request_id;
62         char *req_key;
63         pkgmgr_handler event_cb;
64         void *data;
65         struct _req_cb_info *next;
66 } req_cb_info;
67
68 typedef struct _listen_cb_info {
69         int request_id;
70         pkgmgr_handler event_cb;
71         void *data;
72         struct _listen_cb_info *next;
73 } listen_cb_info;
74
75 typedef struct _pkgmgr_client_t {
76         client_type ctype;
77         int status_type;
78         union {
79                 struct _request {
80                         comm_client *cc;
81                         req_cb_info *rhead;
82                 } request;
83                 struct _listening {
84                         comm_client *cc;
85                         listen_cb_info *lhead;
86                 } listening;
87         } info;
88         void *new_event_cb;
89 } pkgmgr_client_t;
90
91 typedef struct _iter_data {
92         pkgmgr_iter_fn iter_fn;
93         void *data;
94 } iter_data;
95
96 static int __xsystem(const char *argv[])
97 {
98         int status = 0;
99         pid_t pid;
100         pid = fork();
101         switch (pid) {
102         case -1:
103                 perror("fork failed");
104                 return -1;
105         case 0:
106                 /* child */
107                 execvp(argv[0], (char *const *)argv);
108                 _exit(-1);
109         default:
110                 /* parent */
111                 break;
112         }
113         if (waitpid(pid, &status, 0) == -1) {
114                 perror("waitpid failed");
115                 return -1;
116         }
117         if (WIFSIGNALED(status)) {
118                 perror("signal");
119                 return -1;
120         }
121         if (!WIFEXITED(status)) {
122                 /* shouldn't happen */
123                 perror("should not happen");
124                 return -1;
125         }
126         return WEXITSTATUS(status);
127 }
128
129 static void __error_to_string(int errnumber, char **errstr)
130 {
131         if (errstr == NULL)
132                 return;
133         switch (errnumber) {
134         case PKGCMD_ERR_PACKAGE_NOT_FOUND:
135                 *errstr = PKGCMD_ERR_PACKAGE_NOT_FOUND_STR;
136                 break;
137         case PKGCMD_ERR_PACKAGE_INVALID:
138                 *errstr = PKGCMD_ERR_PACKAGE_INVALID_STR;
139                 break;
140         case PKGCMD_ERR_PACKAGE_LOWER_VERSION:
141                 *errstr = PKGCMD_ERR_PACKAGE_LOWER_VERSION_STR;
142                 break;
143         case PKGCMD_ERR_PACKAGE_EXECUTABLE_NOT_FOUND:
144                 *errstr = PKGCMD_ERR_PACKAGE_EXECUTABLE_NOT_FOUND_STR;
145                 break;
146         case PKGCMD_ERR_MANIFEST_INVALID:
147                 *errstr = PKGCMD_ERR_MANIFEST_INVALID_STR;
148                 break;
149         case PKGCMD_ERR_CONFIG_NOT_FOUND:
150                 *errstr = PKGCMD_ERR_CONFIG_NOT_FOUND_STR;
151                 break;
152         case PKGCMD_ERR_CONFIG_INVALID:
153                 *errstr = PKGCMD_ERR_CONFIG_INVALID_STR;
154                 break;
155         case PKGCMD_ERR_SIGNATURE_NOT_FOUND:
156                 *errstr = PKGCMD_ERR_SIGNATURE_NOT_FOUND_STR;
157                 break;
158         case PKGCMD_ERR_SIGNATURE_INVALID:
159                 *errstr = PKGCMD_ERR_SIGNATURE_INVALID_STR;
160                 break;
161         case PKGCMD_ERR_SIGNATURE_VERIFICATION_FAILED:
162                 *errstr = PKGCMD_ERR_SIGNATURE_VERIFICATION_FAILED_STR;
163                 break;
164         case PKGCMD_ERR_ROOT_CERTIFICATE_NOT_FOUND:
165                 *errstr = PKGCMD_ERR_ROOT_CERTIFICATE_NOT_FOUND_STR;
166                 break;
167         case PKGCMD_ERR_CERTIFICATE_INVALID:
168                 *errstr = PKGCMD_ERR_CERTIFICATE_INVALID_STR;
169                 break;
170         case PKGCMD_ERR_CERTIFICATE_CHAIN_VERIFICATION_FAILED:
171                 *errstr = PKGCMD_ERR_CERTIFICATE_CHAIN_VERIFICATION_FAILED_STR;
172                 break;
173         case PKGCMD_ERR_CERTIFICATE_EXPIRED:
174                 *errstr = PKGCMD_ERR_CERTIFICATE_EXPIRED_STR;
175                 break;
176         case PKGCMD_ERR_INVALID_PRIVILEGE:
177                 *errstr = PKGCMD_ERR_INVALID_PRIVILEGE_STR;
178                 break;
179         case PKGCMD_ERR_MENU_ICON_NOT_FOUND:
180                 *errstr = PKGCMD_ERR_MENU_ICON_NOT_FOUND_STR;
181                 break;
182         case PKGCMD_ERR_FATAL_ERROR:
183                 *errstr = PKGCMD_ERR_FATAL_ERROR_STR;
184                 break;
185         case PKGCMD_ERR_OUT_OF_STORAGE:
186                 *errstr = PKGCMD_ERR_OUT_OF_STORAGE_STR;
187                 break;
188         case PKGCMD_ERR_OUT_OF_MEMORY:
189                 *errstr = PKGCMD_ERR_OUT_OF_MEMORY_STR;
190                 break;
191         case PKGCMD_ERR_ARGUMENT_INVALID:
192                 *errstr = PKGCMD_ERR_ARGUMENT_INVALID_STR;
193                 break;
194         default:
195                 *errstr = PKGCMD_ERR_UNKNOWN_STR;
196                 break;
197         }
198 }
199
200 static void __add_op_cbinfo(pkgmgr_client_t * pc, int request_id,
201                             const char *req_key, pkgmgr_handler event_cb, void *new_event_cb,
202                             void *data)
203 {
204         req_cb_info *cb_info;
205         req_cb_info *current;
206         req_cb_info *prev;
207
208         cb_info = (req_cb_info *) calloc(1, sizeof(req_cb_info));
209         if (cb_info == NULL) {
210                 DBG("calloc failed");
211                 return;
212         }
213         cb_info->request_id = request_id;
214         cb_info->req_key = strdup(req_key);
215         cb_info->event_cb = event_cb;
216         cb_info->data = data;
217         cb_info->next = NULL;
218         pc->new_event_cb = new_event_cb;
219
220         if (pc->info.request.rhead == NULL)
221                 pc->info.request.rhead = cb_info;
222         else {
223                 current = prev = pc->info.request.rhead;
224                 while (current) {
225                         prev = current;
226                         current = current->next;
227                 }
228
229                 prev->next = cb_info;
230         }
231 }
232
233 static req_cb_info *__find_op_cbinfo(pkgmgr_client_t *pc, const char *req_key)
234 {
235         req_cb_info *tmp;
236
237         tmp = pc->info.request.rhead;
238
239         if (tmp == NULL) {
240                 ERR("tmp is NULL");
241                 return NULL;
242         }
243
244         DBG("tmp->req_key %s, req_key %s", tmp->req_key, req_key);
245
246         while (tmp) {
247                 if (strncmp(tmp->req_key, req_key, strlen(tmp->req_key)) == 0)
248                         return tmp;
249                 tmp = tmp->next;
250         }
251         return NULL;
252 }
253
254 static void __add_stat_cbinfo(pkgmgr_client_t *pc, int request_id,
255                               pkgmgr_handler event_cb, void *data)
256 {
257         listen_cb_info *cb_info;
258         listen_cb_info *current;
259         listen_cb_info *prev;
260
261         cb_info = (listen_cb_info *) calloc(1, sizeof(listen_cb_info));
262         if (cb_info == NULL) {
263                 DBG("calloc failed");
264                 return;
265         }
266         cb_info->request_id = request_id;
267         cb_info->event_cb = event_cb;
268         cb_info->data = data;
269         cb_info->next = NULL;
270
271         /* TODO - check the order of callback - FIFO or LIFO => Should be changed to LIFO */
272         if (pc->info.listening.lhead == NULL)
273                 pc->info.listening.lhead = cb_info;
274         else {
275                 current = prev = pc->info.listening.lhead;
276                 while (current) {
277                         prev = current;
278                         current = current->next;
279                 }
280
281                 prev->next = cb_info;
282         }
283 }
284
285 static void __operation_callback(void *cb_data, uid_t target_uid,
286                                  const char *req_id, const char *pkg_type,
287                                  const char *pkgid, const char *key,
288                                  const char *val)
289 {
290         pkgmgr_client_t *pc;
291         req_cb_info *cb_info;
292
293         pc = (pkgmgr_client_t *) cb_data;
294
295         /* find callback info */
296         cb_info = __find_op_cbinfo(pc, req_id);
297         if (cb_info == NULL) {
298                 ERR("cannot fint cb_info for req_id:%s", req_id);
299                 return;
300         }
301
302         /* call callback */
303         if (cb_info->event_cb) {
304                 if (pc->new_event_cb)
305                         cb_info->event_cb(target_uid, cb_info->request_id,
306                                         pkg_type, pkgid, key, val, pc,
307                                         cb_info->data);
308                 else
309                         cb_info->event_cb(target_uid, cb_info->request_id,
310                                         pkg_type, pkgid, key, val, NULL,
311                                         cb_info->data);
312         }
313
314         return;
315 }
316
317 static void __status_callback(void *cb_data, uid_t target_uid,
318                               const char *req_id, const char *pkg_type,
319                               const char *pkgid,  const char *key,
320                               const char *val)
321 {
322         pkgmgr_client_t *pc;
323         listen_cb_info *tmp;
324
325         pc = (pkgmgr_client_t *) cb_data;
326
327         tmp = pc->info.listening.lhead;
328         while (tmp) {
329                 if (tmp->event_cb(target_uid, tmp->request_id, pkg_type, pkgid,
330                                   key, val, NULL, tmp->data) != 0)
331                         break;
332                 tmp = tmp->next;
333         }
334
335         return;
336 }
337
338 static inline int __read_proc(const char *path, char *buf, int size)
339 {
340         int fd = 0;
341         int ret = 0;
342
343         if (buf == NULL || path == NULL)
344                 return -1;
345
346         fd = open(path, O_RDONLY);
347         if (fd < 0)
348                 return -1;
349
350         ret = read(fd, buf, size - 1);
351         if (ret <= 0) {
352                 close(fd);
353                 return -1;
354         } else
355                 buf[ret] = 0;
356
357         close(fd);
358
359         return ret;
360 }
361
362 char *__proc_get_cmdline_bypid(int pid)
363 {
364         char buf[PKG_STRING_LEN_MAX] = {'\0', };
365         int ret = 0;
366
367         snprintf(buf, sizeof(buf), "/proc/%d/cmdline", pid);
368         ret = __read_proc(buf, buf, sizeof(buf));
369         if (ret <= 0)
370                 return NULL;
371
372         /* support app launched by shell script*/
373         if (strncmp(buf, BINSH_NAME, BINSH_SIZE) == 0)
374                 return strdup(&buf[BINSH_SIZE + 1]);
375         else
376                 return strdup(buf);
377 }
378
379 static inline int __pkgmgr_read_proc(const char *path, char *buf, int size)
380 {
381         int fd;
382         int ret;
383
384         if (buf == NULL || path == NULL)
385                 return -1;
386
387         fd = open(path, O_RDONLY);
388         if (fd < 0)
389                 return -1;
390
391         ret = read(fd, buf, size - 1);
392         if (ret <= 0) {
393                 close(fd);
394                 return -1;
395         } else
396                 buf[ret] = 0;
397
398         close(fd);
399
400         return ret;
401 }
402
403 static inline int __pkgmgr_find_pid_by_cmdline(const char *dname,
404                                       const char *cmdline, const char *apppath)
405 {
406         int pid = 0;
407
408         if (strncmp(cmdline, apppath, PKG_STRING_LEN_MAX-1) == 0) {
409                 pid = atoi(dname);
410                 if (pid != getpgid(pid))
411                         pid = 0;
412         }
413
414         return pid;
415 }
416
417 static int __sync_process(const char *req_key)
418 {
419         int ret;
420         char info_file[PKG_STRING_LEN_MAX] = {'\0', };
421         int result = -1;
422         int check_cnt = 0;
423         FILE *fp;
424         char buf[PKG_STRING_LEN_MAX] = {0, };
425
426         snprintf(info_file, PKG_STRING_LEN_MAX, "%s/%s", PKG_SIZE_INFO_PATH, req_key);
427         while(1)
428         {
429                 check_cnt++;
430
431                 if (access(info_file, F_OK) == 0) {
432                         fp = fopen(info_file, "r");
433                         if (fp == NULL) {
434                                 DBG("file is not generated yet.... wait\n");
435                                 usleep(100 * 1000);     /* 100ms sleep*/
436                                 continue;
437                         }
438
439                         if (fgets(buf, PKG_STRING_LEN_MAX, fp) == NULL) {
440                                 ERR("failed to read info file");
441                                 fclose(fp);
442                                 break;
443                         }
444                         fclose(fp);
445
446                         DBG("info_file file is generated, result = %s. \n", buf);
447                         result = atoi(buf);
448                         break;
449                 }
450
451                 DBG("file is not generated yet.... wait\n");
452                 usleep(100 * 1000);     /* 100ms sleep*/
453
454                 if (check_cnt > 6000) { /* 60s * 10 time over*/
455                         ERR("wait time over!!\n");
456                         break;
457                 }
458         }
459
460         ret = remove(info_file);
461         if (ret < 0)
462                 ERR("file is can not remove[%s, %d]\n", info_file, ret);
463
464         return result;
465 }
466
467 static int __csc_process(const char *csc_path, char *result_path)
468 {
469         int ret = 0;
470         int cnt = 0;
471         int count = 0;
472         int csc_fail = 0;
473         int fd = 0;
474         char *pkgtype = NULL;
475         char *des = NULL;
476         char buf[PKG_STRING_LEN_MAX] = {0,};
477         char type_buf[1024] = { 0 };
478         char des_buf[1024] = { 0 };
479         dictionary *csc = NULL;
480         FILE* file = NULL;
481
482         csc = iniparser_load(csc_path);
483         retvm_if(csc == NULL, PKGMGR_R_EINVAL, "cannot open parse file [%s]", csc_path);
484
485         file = fopen(result_path, "w");
486         tryvm_if(file == NULL, ret = PKGMGR_R_EINVAL, "cannot open result file [%s]", result_path);
487
488         count = iniparser_getint(csc, "csc packages:count", -1);
489         tryvm_if(count == 0, ret = PKGMGR_R_ERROR, "csc [%s] dont have packages", csc_path);
490
491         snprintf(buf, PKG_STRING_LEN_MAX, "[result]\n");
492         fwrite(buf, 1, strlen(buf), file);
493         snprintf(buf, PKG_STRING_LEN_MAX, "count = %d\n", count);
494         fwrite(buf, 1, strlen(buf), file);
495
496         for(cnt = 1 ; cnt <= count ; cnt++)
497         {
498                 snprintf(type_buf, PKG_STRING_LEN_MAX - 1, "csc packages:type_%03d", cnt);
499                 snprintf(des_buf, PKG_STRING_LEN_MAX - 1, "csc packages:description_%03d", cnt);
500
501                 pkgtype = iniparser_getstring(csc, type_buf, NULL);
502                 des = iniparser_getstring(csc, des_buf, NULL);
503                 ret = 0;
504
505                 if (pkgtype == NULL) {
506                         csc_fail++;
507                         snprintf(buf, PKG_STRING_LEN_MAX, "%s = Fail to get pkgtype\n", type_buf);
508                         fwrite(buf, 1, strlen(buf), file);
509                         continue;
510                 } else if (des == NULL) {
511                         csc_fail++;
512                         snprintf(buf, PKG_STRING_LEN_MAX, "%s = Fail to get description\n", des_buf);
513                         fwrite(buf, 1, strlen(buf), file);
514                         continue;
515                 }
516
517                 snprintf(buf, PKG_STRING_LEN_MAX, "type_%03d = %s\n", cnt, pkgtype);
518                 fwrite(buf, 1, strlen(buf), file);
519                 snprintf(buf, PKG_STRING_LEN_MAX, "description_%03d = %s\n", cnt, des);
520                 fwrite(buf, 1, strlen(buf), file);
521
522                 if (strcmp(pkgtype, "tpk") == 0) {
523                         const char *ospinstaller_argv[] = { "/usr/bin/osp-installer", "-c", des, NULL };
524                         ret = __xsystem(ospinstaller_argv);
525                 } else if (strcmp(pkgtype, "wgt")== 0) {
526                         const char *wrtinstaller_argv[] = { "/usr/bin/wrt-installer", "-c", des, NULL };
527                         ret = __xsystem(wrtinstaller_argv);
528                 } else {
529                         csc_fail++;
530                         ret = -1;
531                 }
532
533                 if (ret != 0) {
534                         char *errstr = NULL;
535                         __error_to_string(ret, &errstr);
536                         snprintf(buf, PKG_STRING_LEN_MAX, "result_%03d = fail[%s]\n", cnt, errstr);
537                 }
538                 else
539                         snprintf(buf, PKG_STRING_LEN_MAX, "result_%03d = success\n", cnt);
540
541                 fwrite(buf, 1, strlen(buf), file);
542         }
543
544 catch:
545         iniparser_freedict(csc);
546         if (file != NULL) {
547                 fflush(file);
548                 fd = fileno(file);
549                 fsync(fd);
550                 fclose(file);
551         }
552         return ret;
553 }
554
555 static int __get_size_process(pkgmgr_client * pc, const char *pkgid, uid_t uid,
556                 pkgmgr_getsize_type get_type, pkgmgr_handler event_cb,
557                 void *data)
558 {
559         GVariant *result;
560         int ret = PKGMGR_R_ECOMM;
561         char *req_key = NULL;
562         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
563
564         if (pc == NULL || pkgid == NULL) {
565                 ERR("invalid parameter");
566                 return PKGMGR_R_EINVAL;
567         }
568
569         if (mpc->ctype != PC_REQUEST) {
570                 ERR("mpc->ctype is not PC_REQUEST");
571                 return PKGMGR_R_EINVAL;
572         }
573         result = comm_client_request(mpc->info.request.cc, "getsize",
574                         g_variant_new("(si)", pkgid, get_type));
575         if (result == NULL)
576                 return PKGMGR_R_ECOMM;
577
578         g_variant_get(result, "(i&s)", &ret, &req_key);
579         if (req_key == NULL) {
580                 g_variant_unref(result);
581                 return PKGMGR_R_ECOMM;
582         }
583         if (ret != PKGMGR_R_OK) {
584                 g_variant_unref(result);
585                 return ret;
586         }
587
588         ret = __sync_process(req_key);
589         if (ret < 0)
590                 ERR("get size failed, ret=%d\n", ret);
591
592         g_variant_unref(result);
593
594         return ret;
595 }
596
597 static int __move_pkg_process(pkgmgr_client *pc, const char *pkgid,
598                 const char *pkg_type, uid_t uid, pkgmgr_move_type move_type,
599                 pkgmgr_handler event_cb, void *data)
600 {
601         int ret;
602
603         ret = pkgmgr_client_usr_move(pc, pkg_type, pkgid, move_type, 0, uid);
604         if (ret < 0) {
605                 ERR("move request failed");
606                 return ret;
607         }
608
609         /* FIXME */
610         ret = __sync_process(pkgid);
611         if (ret != 0)
612                 ERR("move pkg failed, ret=%d\n", ret);
613
614         return ret;
615 }
616
617 static int __check_app_process(pkgmgr_request_service_type service_type,
618                 pkgmgr_client *pc, const char *pkgid, uid_t uid, void *data)
619 {
620         GVariant *result = NULL;
621         int ret = PKGMGR_R_ECOMM;
622         pkgmgrinfo_pkginfo_h handle;
623         int pid = -1;
624         pkgmgr_client_t *mpc = (pkgmgr_client_t *) pc;
625
626         retvm_if(mpc->ctype != PC_REQUEST, PKGMGR_R_EINVAL, "mpc->ctype is not PC_REQUEST\n");
627
628         if (uid != GLOBAL_USER)
629                 ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &handle);
630         else
631                 ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgid, &handle);
632         retvm_if(ret < 0, PKGMGR_R_ERROR, "pkgmgrinfo_pkginfo_get_pkginfo failed");
633
634         if (service_type == PM_REQUEST_KILL_APP)
635                 result = comm_client_request(mpc->info.request.cc, "kill",
636                                 g_variant_new("(s)", pkgid));
637         else if (service_type == PM_REQUEST_CHECK_APP)
638                 result = comm_client_request(mpc->info.request.cc, "check",
639                                 g_variant_new("(s)", pkgid));
640
641         if (result == NULL)
642                 return PKGMGR_R_ECOMM;
643         g_variant_get(result, "(i)", &ret);
644         g_variant_unref(result);
645         if (ret != PKGMGR_R_OK) {
646                 ERR("request failed, ret=%d", ret);
647                 return ret;
648         }
649
650         /* FIXME */
651         pid  = __sync_process(pkgid);
652         *(int *)data = pid;
653
654         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
655
656         return ret;
657
658 }
659
660 static int __request_size_info(pkgmgr_client *pc, uid_t uid)
661 {
662         GVariant *result;
663         int ret = PKGMGR_R_ECOMM;
664         char *req_key = NULL;
665         pkgmgr_client_t *mpc = (pkgmgr_client_t *) pc;
666
667         if (pc == NULL) {
668                 ERR("invalid parameter");
669                 return PKGMGR_R_EINVAL;
670         }
671
672         if (mpc->ctype != PC_REQUEST) {
673                 ERR("mpc->ctype is not PC_REQUEST");
674                 return PKGMGR_R_EINVAL;
675         }
676
677         result = comm_client_request(mpc->info.request.cc, "getsize",
678                         g_variant_new("(si)", "size_info", PM_GET_SIZE_INFO));
679         if (result == NULL)
680                 return PKGMGR_R_ECOMM;
681
682         g_variant_get(result, "(i&s)", &ret, &req_key);
683         if (req_key == NULL) {
684                 g_variant_unref(result);
685                 return PKGMGR_R_ECOMM;
686         }
687
688         g_variant_unref(result);
689
690         return ret;
691 }
692
693 static int __change_op_cb_for_getsize(pkgmgr_client *pc)
694 {
695         int ret = -1;
696
697         retvm_if(pc == NULL, PKGMGR_R_EINVAL, "package manager client pc is NULL");
698         pkgmgr_client_t *mpc = (pkgmgr_client_t *) pc;
699
700         /*  free listening head */
701         req_cb_info *tmp = NULL;
702         req_cb_info *prev = NULL;
703         for (tmp = mpc->info.request.rhead; tmp;) {
704                 prev = tmp;
705                 tmp = tmp->next;
706                 free(prev);
707         }
708
709         /* free dbus connection */
710         ret = comm_client_free(mpc->info.request.cc);
711         retvm_if(ret < 0, PKGMGR_R_ERROR, "comm_client_free() failed - %d", ret);
712
713         /* Manage pc for seperated event */
714         mpc->ctype = PC_REQUEST;
715         mpc->status_type = PKGMGR_CLIENT_STATUS_GET_SIZE;
716
717
718         mpc->info.request.cc = comm_client_new();
719         retvm_if(mpc->info.request.cc == NULL, PKGMGR_R_ERROR, "client creation failed");
720
721         ret = comm_client_set_status_callback(COMM_STATUS_BROADCAST_GET_SIZE, mpc->info.request.cc, __operation_callback, pc);
722         retvm_if(ret < 0, PKGMGR_R_ERROR, "set_status_callback() failed - %d", ret);
723
724         return PKGMGR_R_OK;
725 }
726
727 static int __get_pkg_size_info_cb(uid_t target_uid, int req_id, const char *req_type,
728                 const char *pkgid, const char *key,
729                 const char *value, const void *pc, void *user_data)
730 {
731         int ret = 0;
732         DBG("target_uid: %u, reqid: %d, req type: %s, pkgid: %s, unused key: %s, size info: %s",
733                         target_uid, req_id, req_type, pkgid, key, value);
734
735         pkg_size_info_t *size_info = (pkg_size_info_t *)malloc(sizeof(pkg_size_info_t));
736         retvm_if(size_info == NULL, -1, "The memory is insufficient.");
737
738         char *save_ptr = NULL;
739         char *token = strtok_r((char*)value, ":", &save_ptr);
740         tryvm_if(token == NULL, ret = -1, "failed to parse sizeinfo");
741         size_info->data_size = atoll(token);
742         token = strtok_r(NULL, ":", &save_ptr);
743         tryvm_if(token == NULL, ret = -1, "failed to parse sizeinfo");
744         size_info->cache_size = atoll(token);
745         token = strtok_r(NULL, ":", &save_ptr);
746         tryvm_if(token == NULL, ret = -1, "failed to parse sizeinfo");
747         size_info->app_size = atoll(token);
748         token = strtok_r(NULL, ":", &save_ptr);
749         tryvm_if(token == NULL, ret = -1, "failed to parse sizeinfo");
750         size_info->ext_data_size = atoll(token);
751         token = strtok_r(NULL, ":", &save_ptr);
752         tryvm_if(token == NULL, ret = -1, "failed to parse sizeinfo");
753         size_info->ext_cache_size = atoll(token);
754         token = strtok_r(NULL, ":", &save_ptr);
755         tryvm_if(token == NULL, ret = -1, "failed to parse sizeinfo");
756         size_info->ext_app_size = atoll(token);
757
758         DBG("data: %lld, cache: %lld, app: %lld, ext_data: %lld, ext_cache: %lld, ext_app: %lld",
759                         size_info->data_size, size_info->cache_size, size_info->app_size,
760                         size_info->ext_data_size, size_info->ext_cache_size, size_info->ext_app_size);
761
762         pkgmgr_client_t *pmc = (pkgmgr_client_t *)pc;
763         tryvm_if(pmc == NULL, ret = -1, "pkgmgr_client instance is null.");
764
765         if (strcmp(pkgid, PKG_SIZE_INFO_TOTAL) == 0)
766         {       // total package size info
767                 pkgmgr_total_pkg_size_info_receive_cb callback = (pkgmgr_total_pkg_size_info_receive_cb)(pmc->new_event_cb);
768                 callback((pkgmgr_client *)pc, size_info, user_data);
769         }
770         else
771         {
772                 pkgmgr_pkg_size_info_receive_cb callback = (pkgmgr_pkg_size_info_receive_cb)(pmc->new_event_cb);
773                 callback((pkgmgr_client *)pc, pkgid, size_info, user_data);
774         }
775
776 catch:
777
778         if(size_info){
779                 free(size_info);
780                 size_info = NULL;
781         }
782         return ret;
783 }
784
785 API pkgmgr_client *pkgmgr_client_new(client_type ctype)
786 {
787         pkgmgr_client_t *pc = NULL;
788         int ret = -1;
789
790         retvm_if(ctype == PC_BROADCAST, NULL, "broadcast type is not supported");
791         retvm_if(ctype != PC_REQUEST && ctype != PC_LISTENING, NULL, "ctype is not client_type");
792
793         /* Allocate memory for ADT:pkgmgr_client */
794         pc = calloc(1, sizeof(pkgmgr_client_t));
795         retvm_if(pc == NULL, NULL, "No memory");
796
797         /* Manage pc */
798         pc->ctype = ctype;
799         pc->status_type = PKGMGR_CLIENT_STATUS_ALL;
800
801         if (pc->ctype == PC_REQUEST) {
802                 pc->info.request.cc = comm_client_new();
803                 trym_if(pc->info.request.cc == NULL, "client creation failed");
804
805                 ret = comm_client_set_status_callback(COMM_STATUS_BROADCAST_ALL, pc->info.request.cc, __operation_callback, pc);
806                 trym_if(ret < 0L, "comm_client_set_status_callback() failed - %d", ret);
807         } else if (pc->ctype == PC_LISTENING) {
808                 pc->info.listening.cc = comm_client_new();
809                 trym_if(pc->info.listening.cc == NULL, "client creation failed");
810
811                 ret = comm_client_set_status_callback(COMM_STATUS_BROADCAST_ALL, pc->info.listening.cc, __status_callback, pc);
812                 trym_if(ret < 0L, "comm_client_set_status_callback() failed - %d", ret);
813         }
814
815         return (pkgmgr_client *) pc;
816
817  catch:
818         if (pc)
819                 free(pc);
820         return NULL;
821 }
822
823 API int pkgmgr_client_free(pkgmgr_client *pc)
824 {
825         int ret = -1;
826         pkgmgr_client_t *mpc = (pkgmgr_client_t *) pc;
827         retvm_if(mpc == NULL, PKGMGR_R_EINVAL, "Invalid argument");
828
829         if (mpc->ctype == PC_REQUEST) {
830                 req_cb_info *tmp;
831                 req_cb_info *prev;
832                 for (tmp = mpc->info.request.rhead; tmp;) {
833                         prev = tmp;
834                         tmp = tmp->next;
835                         free(prev);
836                 }
837
838                 ret = comm_client_free(mpc->info.request.cc);
839                 tryvm_if(ret < 0, ret = PKGMGR_R_ERROR, "comm_client_free() failed");
840         } else if (mpc->ctype == PC_LISTENING) {
841                         listen_cb_info *tmp;
842                         listen_cb_info *prev;
843                         for (tmp = mpc->info.listening.lhead; tmp;) {
844                                 prev = tmp;
845                                 tmp = tmp->next;
846                                 free(prev);
847                         }
848
849                         ret = comm_client_free(mpc->info.listening.cc);
850                         tryvm_if(ret < 0, ret = PKGMGR_R_ERROR, "comm_client_free() failed");
851         } else if (mpc->ctype == PC_BROADCAST) {
852                 ret = 0;
853         } else {
854                 ERR("Invalid client type\n");
855                 return PKGMGR_R_EINVAL;
856         }
857
858         free(mpc);
859         mpc = NULL;
860         return PKGMGR_R_OK;
861
862  catch:
863         if (mpc) {
864                 free(mpc);
865                 mpc = NULL;
866         }
867         return PKGMGR_R_ERROR;
868 }
869
870 static char *__get_type_from_path(const char *pkg_path)
871 {
872         int ret;
873         char mimetype[255] = { '\0', };
874         char extlist[256] = { '\0', };
875         char *pkg_type;
876
877         ret = _get_mime_from_file(pkg_path, mimetype, sizeof(mimetype));
878         if (ret) {
879                 ERR("_get_mime_from_file() failed - error code[%d]\n", ret);
880                 return NULL;
881         }
882
883         ret = _get_mime_extension(mimetype, extlist, sizeof(extlist));
884         if (ret) {
885                 ERR("_get_mime_extension() failed - error code[%d]\n", ret);
886                 return NULL;
887         }
888
889         if (strlen(extlist) == 0)
890                 return NULL;
891
892         if (strchr(extlist, ','))
893                 extlist[strlen(extlist) - strlen(strchr(extlist, ','))] = '\0';
894
895         pkg_type = strchr(extlist, '.') + 1;
896         return strdup(pkg_type);
897 }
898
899 API int pkgmgr_client_usr_install(pkgmgr_client *pc, const char *pkg_type,
900                 const char *descriptor_path, const char *pkg_path,
901                 const char *optional_file, pkgmgr_mode mode,
902                 pkgmgr_handler event_cb, void *data, uid_t uid)
903 {
904         GVariant *result;
905         int ret = PKGMGR_R_ECOMM;
906         char *req_key = NULL;
907         int req_id;
908         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
909         char *pkgtype;
910
911         if (pc == NULL || pkg_path == NULL) {
912                 ERR("invalid parameter");
913                 return PKGMGR_R_EINVAL;
914         }
915
916         if (mpc->ctype != PC_REQUEST) {
917                 ERR("mpc->ctype is not PC_REQUEST");
918                 return PKGMGR_R_EINVAL;
919         }
920
921         /* TODO: check pkg's type on server-side */
922         if (pkg_type == NULL)
923                 pkgtype = __get_type_from_path(pkg_path);
924         else
925                 pkgtype = strdup(pkg_type);
926
927         result = comm_client_request(mpc->info.request.cc, "install",
928                         g_variant_new("(ss)", pkgtype, pkg_path));
929         free(pkgtype);
930         if (result == NULL)
931                 return PKGMGR_R_ECOMM;
932         g_variant_get(result, "(i&s)", &ret, &req_key);
933         if (req_key == NULL) {
934                 g_variant_unref(result);
935                 return PKGMGR_R_ECOMM;
936         }
937         if (ret != PKGMGR_R_OK) {
938                 g_variant_unref(result);
939                 return ret;
940         }
941
942         req_id = _get_request_id();
943         __add_op_cbinfo(mpc, req_id, req_key, event_cb, NULL, data);
944
945         g_variant_unref(result);
946
947         return req_id;
948 }
949
950 API int pkgmgr_client_install(pkgmgr_client *pc, const char *pkg_type,
951                 const char *descriptor_path, const char *pkg_path,
952                 const char *optional_file, pkgmgr_mode mode,
953                 pkgmgr_handler event_cb, void *data)
954 {
955         return pkgmgr_client_usr_install(pc, pkg_type, descriptor_path,
956                         pkg_path, optional_file, mode, event_cb,data,
957                         GLOBAL_USER);
958 }
959
960 API int pkgmgr_client_reinstall(pkgmgr_client *pc, const char *pkg_type,
961                 const char *pkgid, const char *optional_file, pkgmgr_mode mode,
962                 pkgmgr_handler event_cb, void *data)
963 {
964         return pkgmgr_client_usr_reinstall(pc, pkg_type, pkgid, optional_file,
965                         mode, event_cb, data,GLOBAL_USER);
966 }
967
968 API int pkgmgr_client_usr_reinstall(pkgmgr_client * pc, const char *pkg_type,
969                 const char *pkgid, const char *optional_file, pkgmgr_mode mode,
970                 pkgmgr_handler event_cb, void *data, uid_t uid)
971 {
972         GVariant *result;
973         int ret = PKGMGR_R_ECOMM;
974         char *req_key = NULL;
975         int req_id;
976         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
977         char *pkgtype;
978         pkgmgrinfo_pkginfo_h handle;
979
980         if (pc == NULL || pkgid == NULL) {
981                 ERR("invalid parameter");
982                 return PKGMGR_R_EINVAL;
983         }
984
985         if (mpc->ctype != PC_REQUEST) {
986                 ERR("mpc->ctype is not PC_REQUEST");
987                 return PKGMGR_R_EINVAL;
988         }
989
990         ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &handle);
991         if (ret < 0)
992                 return PKGMGR_R_EINVAL;
993
994         ret = pkgmgrinfo_pkginfo_get_type(handle, &pkgtype);
995         if (ret < 0) {
996                 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
997                 return PKGMGR_R_ERROR;
998         }
999
1000         result = comm_client_request(mpc->info.request.cc, "reinstall",
1001                         g_variant_new("(ss)", pkgtype, pkgid));
1002         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1003         if (result == NULL)
1004                 return PKGMGR_R_ECOMM;
1005         g_variant_get(result, "(i&s)", &ret, &req_key);
1006         if (req_key == NULL) {
1007                 g_variant_unref(result);
1008                 return PKGMGR_R_ECOMM;
1009         }
1010         if (ret != PKGMGR_R_OK) {
1011                 g_variant_unref(result);
1012                 return ret;
1013         }
1014
1015         req_id = _get_request_id();
1016         __add_op_cbinfo(mpc, req_id, req_key, event_cb, NULL, data);
1017
1018         g_variant_unref(result);
1019
1020         return req_id;
1021 }
1022
1023 API int pkgmgr_client_uninstall(pkgmgr_client *pc, const char *pkg_type,
1024                 const char *pkgid, pkgmgr_mode mode, pkgmgr_handler event_cb,
1025                 void *data)
1026 {
1027         return pkgmgr_client_usr_uninstall(pc, pkg_type,pkgid, mode, event_cb,
1028                         data, GLOBAL_USER);
1029 }
1030
1031 API int pkgmgr_client_usr_uninstall(pkgmgr_client *pc, const char *pkg_type,
1032                 const char *pkgid, pkgmgr_mode mode, pkgmgr_handler event_cb,
1033                 void *data, uid_t uid)
1034 {
1035         GVariant *result;
1036         int ret = PKGMGR_R_ECOMM;
1037         char *req_key = NULL;
1038         int req_id;
1039         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1040         char *pkgtype;
1041         pkgmgrinfo_pkginfo_h handle;
1042
1043         if (pc == NULL || pkgid == NULL) {
1044                 ERR("invalid parameter");
1045                 return PKGMGR_R_EINVAL;
1046         }
1047
1048         if (mpc->ctype != PC_REQUEST) {
1049                 ERR("mpc->ctype is not PC_REQUEST");
1050                 return PKGMGR_R_EINVAL;
1051         }
1052
1053         ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &handle);
1054         if (ret < 0)
1055                 return PKGMGR_R_EINVAL;
1056
1057         ret = pkgmgrinfo_pkginfo_get_type(handle, &pkgtype);
1058         if (ret < 0) {
1059                 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1060                 return PKGMGR_R_ERROR;
1061         }
1062
1063         /* TODO: check removable ? */
1064
1065         result = comm_client_request(mpc->info.request.cc, "uninstall",
1066                         g_variant_new("(ss)", pkgtype, pkgid));
1067         if (result == NULL) {
1068                 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1069                 return PKGMGR_R_ECOMM;
1070         }
1071         g_variant_get(result, "(i&s)", &ret, &req_key);
1072         if (req_key == NULL) {
1073                 g_variant_unref(result);
1074                 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1075                 return PKGMGR_R_ECOMM;
1076         }
1077         if (ret != PKGMGR_R_OK) {
1078                 g_variant_unref(result);
1079                 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1080                 return ret;
1081         }
1082
1083         req_id = _get_request_id();
1084         __add_op_cbinfo(mpc, req_id, req_key, event_cb, NULL, data);
1085
1086         g_variant_unref(result);
1087         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1088
1089         return req_id;
1090 }
1091
1092 API int pkgmgr_client_move(pkgmgr_client *pc, const char *pkg_type,
1093                 const char *pkgid, pkgmgr_move_type move_type, pkgmgr_mode mode)
1094 {
1095         return pkgmgr_client_usr_move(pc, pkg_type, pkgid, move_type, mode,
1096                         GLOBAL_USER);
1097 }
1098 API int pkgmgr_client_usr_move(pkgmgr_client *pc, const char *pkg_type,
1099                 const char *pkgid, pkgmgr_move_type move_type,
1100                 pkgmgr_mode mode, uid_t uid)
1101 {
1102         GVariant *result;
1103         int ret = PKGMGR_R_ECOMM;
1104         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1105
1106         if (pc == NULL || pkg_type == NULL || pkgid == NULL) {
1107                 ERR("invalid parameter");
1108                 return PKGMGR_R_EINVAL;
1109         }
1110
1111         if ((move_type < PM_MOVE_TO_INTERNAL) || (move_type > PM_MOVE_TO_SDCARD))
1112                 return PKGMGR_R_EINVAL;
1113
1114         if (mpc->ctype != PC_REQUEST) {
1115                 ERR("mpc->ctype is not PC_REQUEST");
1116                 return PKGMGR_R_EINVAL;
1117         }
1118
1119         result = comm_client_request(mpc->info.request.cc, "move",
1120                         g_variant_new("(ss)", pkg_type, pkgid));
1121         if (result == NULL)
1122                 return PKGMGR_R_ECOMM;
1123         g_variant_get(result, "(i)", &ret);
1124         g_variant_unref(result);
1125
1126         return ret;
1127 }
1128
1129 API int pkgmgr_client_usr_activate(pkgmgr_client *pc, const char *pkg_type,
1130                 const char *pkgid, uid_t uid)
1131 {
1132         GVariant *result;
1133         int ret = PKGMGR_R_ECOMM;
1134         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1135
1136         if (pc == NULL || pkgid == NULL) {
1137                 ERR("invalid parameter");
1138                 return PKGMGR_R_EINVAL;
1139         }
1140
1141         result = comm_client_request(mpc->info.request.cc, "enable_pkg",
1142                         g_variant_new("(s)", pkgid));
1143         if (result == NULL)
1144                 return PKGMGR_R_ECOMM;
1145         g_variant_get(result, "(i)", &ret);
1146         g_variant_unref(result);
1147
1148         return ret;
1149 }
1150
1151 API int pkgmgr_client_activate(pkgmgr_client *pc, const char *pkg_type,
1152                 const char *pkgid)
1153 {
1154         return pkgmgr_client_usr_activate(pc, pkg_type, pkgid, GLOBAL_USER);
1155 }
1156
1157 API int pkgmgr_client_usr_deactivate(pkgmgr_client *pc, const char *pkg_type,
1158                                  const char *pkgid, uid_t uid)
1159 {
1160         GVariant *result;
1161         int ret = PKGMGR_R_ECOMM;
1162         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1163
1164         if (pc == NULL || pkgid == NULL) {
1165                 ERR("invalid parameter");
1166                 return PKGMGR_R_EINVAL;
1167         }
1168
1169         result = comm_client_request(mpc->info.request.cc, "disable_pkg",
1170                         g_variant_new("(s)", pkgid));
1171         if (result == NULL)
1172                 return PKGMGR_R_ECOMM;
1173         g_variant_get(result, "(i)", &ret);
1174         g_variant_unref(result);
1175
1176         return ret;
1177 }
1178
1179 API int pkgmgr_client_deactivate(pkgmgr_client *pc, const char *pkg_type,
1180                                  const char *pkgid)
1181 {
1182         return pkgmgr_client_usr_deactivate(pc, pkg_type, pkgid, GLOBAL_USER);
1183 }
1184
1185 API int pkgmgr_client_usr_activate_app(pkgmgr_client *pc, const char *appid,
1186                 uid_t uid)
1187 {
1188         GVariant *result;
1189         int ret = PKGMGR_R_ECOMM;
1190         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1191
1192         if (pc == NULL || appid == NULL) {
1193                 ERR("invalid parameter");
1194                 return PKGMGR_R_EINVAL;
1195         }
1196
1197         result = comm_client_request(mpc->info.request.cc, "enable_app",
1198                         g_variant_new("(s)", appid));
1199         if (result == NULL)
1200                 return PKGMGR_R_ECOMM;
1201         g_variant_get(result, "(i)", &ret);
1202         g_variant_unref(result);
1203
1204         return ret;
1205 }
1206
1207 API int pkgmgr_client_activate_app(pkgmgr_client * pc, const char *appid)
1208 {
1209         return pkgmgr_client_usr_activate_app(pc, appid, GLOBAL_USER);
1210 }
1211
1212 /* TODO: deprecate? */
1213 API int pkgmgr_client_usr_activate_appv(pkgmgr_client *pc, const char *appid,
1214                 char *const argv[], uid_t uid)
1215 {
1216         return pkgmgr_client_usr_activate_app(pc, appid, uid);
1217 }
1218
1219 API int pkgmgr_client_activate_appv(pkgmgr_client *pc, const char *appid,
1220                 char *const argv[])
1221 {
1222         return pkgmgr_client_usr_activate_app(pc, appid, GLOBAL_USER);
1223 }
1224
1225 API int pkgmgr_client_usr_deactivate_app(pkgmgr_client *pc, const char *appid,
1226                 uid_t uid)
1227 {
1228         GVariant *result;
1229         int ret = PKGMGR_R_ECOMM;
1230         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1231
1232         if (pc == NULL || appid == NULL) {
1233                 ERR("invalid parameter");
1234                 return PKGMGR_R_EINVAL;
1235         }
1236
1237         result = comm_client_request(mpc->info.request.cc, "disable_app",
1238                         g_variant_new("(s)", appid));
1239         if (result == NULL)
1240                 return PKGMGR_R_ECOMM;
1241         g_variant_get(result, "(i)", &ret);
1242         g_variant_unref(result);
1243
1244         return ret;
1245 }
1246
1247 API int pkgmgr_client_deactivate_app(pkgmgr_client *pc, const char *appid)
1248 {
1249         return pkgmgr_client_usr_deactivate_app(pc, appid, GLOBAL_USER);
1250 }
1251
1252 API int pkgmgr_client_usr_clear_user_data(pkgmgr_client *pc,
1253                 const char *pkg_type, const char *appid, pkgmgr_mode mode,
1254                 uid_t uid)
1255 {
1256         GVariant *result;
1257         int ret = PKGMGR_R_ECOMM;
1258         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1259
1260         if (pc == NULL || pkg_type == NULL || appid == NULL) {
1261                 ERR("invalid parameter");
1262                 return PKGMGR_R_EINVAL;
1263         }
1264
1265         if (mpc->ctype != PC_REQUEST) {
1266                 ERR("mpc->ctype is not PC_REQUEST");
1267                 return PKGMGR_R_EINVAL;
1268         }
1269
1270         result = comm_client_request(mpc->info.request.cc, "cleardata",
1271                         g_variant_new("(ss)", pkg_type, appid));
1272         if (result == NULL)
1273                 return PKGMGR_R_ECOMM;
1274
1275         g_variant_get(result, "(i)", &ret);
1276         g_variant_unref(result);
1277
1278         return ret;
1279 }
1280
1281 API int pkgmgr_client_clear_user_data(pkgmgr_client *pc, const char *pkg_type,
1282                 const char *appid, pkgmgr_mode mode)
1283 {
1284         return pkgmgr_client_usr_clear_user_data(pc, pkg_type, appid, mode,
1285                         GLOBAL_USER);
1286 }
1287
1288 API int pkgmgr_client_set_status_type(pkgmgr_client *pc, int status_type)
1289 {
1290         int ret = -1;
1291
1292         retvm_if(pc == NULL, PKGMGR_R_EINVAL, "package manager client pc is NULL");
1293         retvm_if(status_type == PKGMGR_CLIENT_STATUS_ALL, PKGMGR_R_OK, "status_type is PKGMGR_CLIENT_STATUS_ALL");
1294         pkgmgr_client_t *mpc = (pkgmgr_client_t *) pc;
1295
1296         /*  free listening head */
1297         listen_cb_info *tmp = NULL;
1298         listen_cb_info *prev = NULL;
1299         for (tmp = mpc->info.listening.lhead; tmp;) {
1300                 prev = tmp;
1301                 tmp = tmp->next;
1302                 free(prev);
1303         }
1304
1305         /* free dbus connection */
1306         ret = comm_client_free(mpc->info.listening.cc);
1307         retvm_if(ret < 0, PKGMGR_R_ERROR, "comm_client_free() failed - %d", ret);
1308
1309         /* Manage pc for seperated event */
1310         mpc->ctype = PC_LISTENING;
1311         mpc->status_type = status_type;
1312
1313         mpc->info.listening.cc = comm_client_new();
1314         retvm_if(mpc->info.listening.cc == NULL, PKGMGR_R_EINVAL, "client creation failed");
1315
1316         if ((mpc->status_type & PKGMGR_CLIENT_STATUS_INSTALL) == PKGMGR_CLIENT_STATUS_INSTALL) {
1317                 ret = comm_client_set_status_callback(COMM_STATUS_BROADCAST_INSTALL, mpc->info.listening.cc, __status_callback, pc);
1318                 retvm_if(ret < 0, PKGMGR_R_ECOMM, "PKGMGR_CLIENT_STATUS_INSTALL failed - %d", ret);
1319         }
1320
1321         if ((mpc->status_type & PKGMGR_CLIENT_STATUS_UNINSTALL) == PKGMGR_CLIENT_STATUS_UNINSTALL) {
1322                 ret = comm_client_set_status_callback(COMM_STATUS_BROADCAST_UNINSTALL, mpc->info.listening.cc, __status_callback, pc);
1323                 retvm_if(ret < 0, PKGMGR_R_ECOMM, "COMM_STATUS_BROADCAST_UNINSTALL failed - %d", ret);
1324         }
1325
1326         if ((mpc->status_type & PKGMGR_CLIENT_STATUS_MOVE) == PKGMGR_CLIENT_STATUS_MOVE) {
1327                 ret = comm_client_set_status_callback(COMM_STATUS_BROADCAST_MOVE, mpc->info.listening.cc, __status_callback, pc);
1328                 retvm_if(ret < 0, PKGMGR_R_ECOMM, "COMM_STATUS_BROADCAST_MOVE failed - %d", ret);
1329         }
1330
1331         if ((mpc->status_type & PKGMGR_CLIENT_STATUS_INSTALL_PROGRESS) == PKGMGR_CLIENT_STATUS_INSTALL_PROGRESS) {
1332                 ret = comm_client_set_status_callback(COMM_STATUS_BROADCAST_INSTALL_PROGRESS, mpc->info.listening.cc, __status_callback, pc);
1333                 retvm_if(ret < 0, PKGMGR_R_ECOMM, "COMM_STATUS_BROADCAST_INSTALL_PROGRESS failed - %d", ret);
1334         }
1335
1336    if ((mpc->status_type & PKGMGR_CLIENT_STATUS_UPGRADE) == PKGMGR_CLIENT_STATUS_UPGRADE) {
1337            ret = comm_client_set_status_callback(COMM_STATUS_BROADCAST_UPGRADE, mpc->info.listening.cc, __status_callback, pc);
1338            retvm_if(ret < 0, PKGMGR_R_ECOMM, "COMM_STATUS_BROADCAST_UPGRADE failed - %d", ret);
1339    }
1340
1341    return PKGMGR_R_OK;
1342 }
1343
1344 API int pkgmgr_client_listen_status(pkgmgr_client *pc, pkgmgr_handler event_cb,
1345                                     void *data)
1346 {
1347         int req_id;
1348         /* Check for NULL value of pc */
1349         retvm_if(pc == NULL, PKGMGR_R_EINVAL, "package manager client pc is NULL");
1350         pkgmgr_client_t *mpc = (pkgmgr_client_t *) pc;
1351
1352         /* 0. check input */
1353         retvm_if(mpc->ctype != PC_LISTENING, PKGMGR_R_EINVAL, "ctype is not PC_LISTENING");
1354         retvm_if(event_cb == NULL, PKGMGR_R_EINVAL, "event_cb is NULL");
1355
1356         /* 1. get id */
1357         req_id = _get_request_id();
1358
1359         /* 2. add callback info to pkgmgr_client */
1360         __add_stat_cbinfo(mpc, req_id, event_cb, data);
1361         return req_id;
1362 }
1363
1364 API int pkgmgr_client_broadcast_status(pkgmgr_client *pc, const char *pkg_type,
1365                                        const char *pkgid, const char *key,
1366                                        const char *val)
1367 {
1368         /* client cannot broadcast signal */
1369         return PKGMGR_R_OK;
1370 }
1371
1372 API int pkgmgr_client_request_service(pkgmgr_request_service_type service_type, int service_mode,
1373                                   pkgmgr_client * pc, const char *pkg_type, const char *pkgid,
1374                               const char *custom_info, pkgmgr_handler event_cb, void *data)
1375 {
1376         return pkgmgr_client_usr_request_service(service_type, service_mode, pc, pkg_type, pkgid, GLOBAL_USER, custom_info, event_cb, data);
1377 }
1378
1379 API int pkgmgr_client_usr_request_service(pkgmgr_request_service_type service_type, int service_mode,
1380                                   pkgmgr_client * pc, const char *pkg_type, const char *pkgid, uid_t uid,
1381                               const char *custom_info, pkgmgr_handler event_cb, void *data)
1382 {
1383         int ret =0;
1384
1385         /* Check for NULL value of service type */
1386         retvm_if(service_type > PM_REQUEST_MAX, PKGMGR_R_EINVAL, "service type is not defined\n");
1387         retvm_if(service_type < 0, PKGMGR_R_EINVAL, "service type is error\n");
1388
1389         switch (service_type) {
1390         case PM_REQUEST_CSC:
1391                 tryvm_if(custom_info == NULL, ret = PKGMGR_R_EINVAL, "custom_info is NULL\n");
1392                 tryvm_if(strlen(custom_info) >= PKG_STRING_LEN_MAX, ret = PKGMGR_R_EINVAL, "optional_file over PKG_STRING_LEN_MAX");
1393                 tryvm_if(data == NULL, ret = PKGMGR_R_EINVAL, "data is NULL\n");
1394
1395                 ret = __csc_process(custom_info, (char *)data);
1396                 if (ret < 0)
1397                         ERR("__csc_process fail \n");
1398                 else
1399                         ret = PKGMGR_R_OK;
1400
1401                 break;
1402
1403         case PM_REQUEST_MOVE:
1404                 tryvm_if(pkgid == NULL, ret = PKGMGR_R_EINVAL, "pkgid is NULL\n");
1405                 tryvm_if(pc == NULL, ret = PKGMGR_R_EINVAL, "pc is NULL\n");
1406                 tryvm_if((service_mode < PM_MOVE_TO_INTERNAL) || (service_mode > PM_MOVE_TO_SDCARD), ret = PKGMGR_R_EINVAL, "service_mode is wrong\n");
1407
1408                 ret = __move_pkg_process(pc, pkgid, pkg_type, uid, (pkgmgr_move_type)service_mode, event_cb, data);
1409                 break;
1410
1411         case PM_REQUEST_GET_SIZE:
1412                 tryvm_if(pkgid == NULL, ret = PKGMGR_R_EINVAL, "pkgid is NULL\n");
1413                 tryvm_if(pc == NULL, ret = PKGMGR_R_EINVAL, "pc is NULL\n");
1414                 tryvm_if((service_mode < PM_GET_TOTAL_SIZE) || (service_mode >= PM_GET_MAX), ret = PKGMGR_R_EINVAL, "service_mode is wrong\n");
1415
1416                 ret = __get_size_process(pc, pkgid, uid, (pkgmgr_getsize_type)service_mode, event_cb, data);
1417                 break;
1418
1419         case PM_REQUEST_KILL_APP:
1420         case PM_REQUEST_CHECK_APP:
1421                 tryvm_if(pkgid == NULL, ret = PKGMGR_R_EINVAL, "pkgid is NULL\n");
1422                 tryvm_if(pc == NULL, ret = PKGMGR_R_EINVAL, "pc is NULL\n");
1423
1424                 ret = __check_app_process(service_type, pc, pkgid, uid, data);
1425                 if (ret < 0)
1426                         ERR("__check_app_process fail \n");
1427                 else
1428                         ret = PKGMGR_R_OK;
1429
1430                 break;
1431
1432         default:
1433                 ERR("Wrong Request\n");
1434                 ret = -1;
1435                 break;
1436         }
1437
1438 catch:
1439
1440         return ret;
1441 }
1442
1443
1444 API int pkgmgr_client_usr_request_size_info(uid_t uid)
1445 {
1446         int ret = 0;
1447         pkgmgr_client *pc = NULL;
1448
1449         pc = pkgmgr_client_new(PC_REQUEST);
1450         retvm_if(pc == NULL, PKGMGR_R_EINVAL, "request pc is null\n");
1451
1452         ret = __request_size_info(pc, uid);
1453         if (ret < 0) {
1454                 ERR("__request_size_info fail \n");
1455         }
1456
1457         pkgmgr_client_free(pc);
1458         return ret;
1459 }
1460
1461 API int pkgmgr_client_request_size_info(void) // get all package size (data, total)
1462 {
1463         return pkgmgr_client_usr_request_size_info(GLOBAL_USER);
1464 }
1465
1466 API int pkgmgr_client_usr_clear_cache_dir(const char *pkgid, uid_t uid)
1467 {
1468         GVariant *result;
1469         int ret = PKGMGR_R_ECOMM;
1470         pkgmgr_client_t *pc;
1471
1472         if (pkgid == NULL) {
1473                 ERR("invalid parameter");
1474                 return PKGMGR_R_EINVAL;
1475         }
1476
1477         pc = pkgmgr_client_new(PC_REQUEST);
1478         if (pc == NULL) {
1479                 ERR("out of memory");
1480                 return PKGMGR_R_ESYSTEM;
1481         }
1482
1483         result = comm_client_request(pc->info.request.cc, "clearcache",
1484                         g_variant_new("(s)", pkgid));
1485         if (result == NULL)
1486                 return PKGMGR_R_ECOMM;
1487         g_variant_get(result, "(i)", &ret);
1488         g_variant_unref(result);
1489
1490         return ret;
1491 }
1492
1493 API int pkgmgr_client_clear_cache_dir(const char *pkgid)
1494 {
1495         return pkgmgr_client_usr_clear_cache_dir(pkgid, GLOBAL_USER);
1496 }
1497
1498 API int pkgmgr_client_clear_usr_all_cache_dir(uid_t uid)
1499 {
1500         return pkgmgr_client_usr_clear_cache_dir(PKG_CLEAR_ALL_CACHE, uid);
1501 }
1502
1503 API int pkgmgr_client_clear_all_cache_dir(void)
1504 {
1505         return pkgmgr_client_usr_clear_cache_dir(PKG_CLEAR_ALL_CACHE, GLOBAL_USER);
1506 }
1507
1508 API int pkgmgr_client_get_size(pkgmgr_client * pc, const char *pkgid,
1509                 pkgmgr_getsize_type get_type, pkgmgr_handler event_cb,
1510                 void *data)
1511 {
1512         return pkgmgr_client_usr_get_size(pc, pkgid, get_type, event_cb, data,
1513                         GLOBAL_USER);
1514 }
1515
1516 API int pkgmgr_client_usr_get_size(pkgmgr_client * pc, const char *pkgid,
1517                 pkgmgr_getsize_type get_type, pkgmgr_handler event_cb,
1518                 void *data, uid_t uid)
1519 {
1520         GVariant *result;
1521         int ret = PKGMGR_R_ECOMM;
1522         char *req_key = NULL;
1523         int req_id;
1524         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1525
1526         if (pc == NULL || pkgid == NULL || event_cb == NULL) {
1527                 ERR("invalid parameter");
1528                 return PKGMGR_R_EINVAL;
1529         }
1530
1531         if (mpc->ctype != PC_REQUEST) {
1532                 ERR("mpc->ctype is not PC_REQUEST");
1533                 return PKGMGR_R_EINVAL;
1534         }
1535
1536         /* FIXME */
1537         if (strcmp(pkgid, PKG_SIZE_INFO_TOTAL) == 0)
1538                 get_type = PM_GET_TOTAL_PKG_SIZE_INFO;
1539         else
1540                 get_type = PM_GET_PKG_SIZE_INFO;
1541         result = comm_client_request(mpc->info.request.cc, "getsize",
1542                         g_variant_new("(si)", pkgid, get_type));
1543         if (result == NULL)
1544                 return PKGMGR_R_ECOMM;
1545
1546         g_variant_get(result, "(i&s)", &ret, &req_key);
1547         if (req_key == NULL) {
1548                 g_variant_unref(result);
1549                 return PKGMGR_R_ECOMM;
1550         }
1551         if (ret != PKGMGR_R_OK) {
1552                 g_variant_unref(result);
1553                 return ret;
1554         }
1555
1556         req_id = _get_request_id();
1557         __add_op_cbinfo(mpc, req_id, req_key, event_cb, NULL, data);
1558
1559         g_variant_unref(result);
1560
1561         return PKGMGR_R_OK;
1562 }
1563
1564 API int pkgmgr_client_usr_get_package_size_info(pkgmgr_client *pc,
1565                 const char *pkgid, pkgmgr_pkg_size_info_receive_cb event_cb,
1566                 void *user_data, uid_t uid)
1567 {
1568         GVariant *result;
1569         int ret = PKGMGR_R_ECOMM;
1570         char *req_key = NULL;
1571         int req_id;
1572         int get_type;
1573         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1574
1575         if (pc == NULL || pkgid == NULL || event_cb == NULL) {
1576                 ERR("invalid parameter");
1577                 return PKGMGR_R_EINVAL;
1578         }
1579
1580         if (mpc->ctype != PC_REQUEST) {
1581                 ERR("mpc->ctype is not PC_REQUEST");
1582                 return PKGMGR_R_EINVAL;
1583         }
1584
1585         /* FIXME */
1586         if (__change_op_cb_for_getsize(mpc) < 0) {
1587                 ERR("__change_op_cb_for_getsize failed");
1588                 return PKGMGR_R_ESYSTEM;
1589         }
1590
1591         if (strcmp(pkgid, PKG_SIZE_INFO_TOTAL) == 0)
1592                 get_type = PM_GET_TOTAL_PKG_SIZE_INFO;
1593         else
1594                 get_type = PM_GET_PKG_SIZE_INFO;
1595         result = comm_client_request(mpc->info.request.cc, "getsize",
1596                         g_variant_new("(si)", pkgid, get_type));
1597         if (result == NULL)
1598                 return PKGMGR_R_ECOMM;
1599
1600         g_variant_get(result, "(i&s)", &ret, &req_key);
1601         if (req_key == NULL) {
1602                 g_variant_unref(result);
1603                 return PKGMGR_R_ECOMM;
1604         }
1605         if (ret != PKGMGR_R_OK) {
1606                 g_variant_unref(result);
1607                 return ret;
1608         }
1609
1610         req_id = _get_request_id();
1611         __add_op_cbinfo(mpc, req_id, req_key, __get_pkg_size_info_cb, event_cb,
1612                         user_data);
1613
1614         g_variant_unref(result);
1615
1616         return PKGMGR_R_OK;
1617 }
1618
1619 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)
1620 {
1621         return pkgmgr_client_usr_get_package_size_info(pc, pkgid, event_cb, user_data, GLOBAL_USER);
1622 }
1623
1624 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)
1625 {       // total package size info
1626         return pkgmgr_client_usr_get_package_size_info(pc, PKG_SIZE_INFO_TOTAL, (pkgmgr_pkg_size_info_receive_cb)event_cb, user_data, uid);
1627 }
1628
1629 API int pkgmgr_client_get_total_package_size_info(pkgmgr_client *pc, pkgmgr_total_pkg_size_info_receive_cb event_cb, void *user_data)
1630 {
1631         return pkgmgr_client_usr_get_package_size_info(pc, PKG_SIZE_INFO_TOTAL, (pkgmgr_pkg_size_info_receive_cb)event_cb, user_data, GLOBAL_USER);
1632 }