Set target uid on dbus method call
[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         if (access(pkg_path, F_OK) != 0) {
922                 ERR("failed to access: %s", pkg_path);
923                 return PKGMGR_R_EINVAL;
924         }
925
926         /* TODO: check pkg's type on server-side */
927         if (pkg_type == NULL)
928                 pkgtype = __get_type_from_path(pkg_path);
929         else
930                 pkgtype = strdup(pkg_type);
931
932         result = comm_client_request(mpc->info.request.cc, "install",
933                         g_variant_new("(uss)", uid, pkgtype, pkg_path));
934         free(pkgtype);
935         if (result == NULL)
936                 return PKGMGR_R_ECOMM;
937         g_variant_get(result, "(i&s)", &ret, &req_key);
938         if (req_key == NULL) {
939                 g_variant_unref(result);
940                 return PKGMGR_R_ECOMM;
941         }
942         if (ret != PKGMGR_R_OK) {
943                 g_variant_unref(result);
944                 return ret;
945         }
946
947         req_id = _get_request_id();
948         __add_op_cbinfo(mpc, req_id, req_key, event_cb, NULL, data);
949
950         g_variant_unref(result);
951
952         return req_id;
953 }
954
955 API int pkgmgr_client_install(pkgmgr_client *pc, const char *pkg_type,
956                 const char *descriptor_path, const char *pkg_path,
957                 const char *optional_file, pkgmgr_mode mode,
958                 pkgmgr_handler event_cb, void *data)
959 {
960         return pkgmgr_client_usr_install(pc, pkg_type, descriptor_path,
961                         pkg_path, optional_file, mode, event_cb,data,
962                         GLOBAL_USER);
963 }
964
965 API int pkgmgr_client_reinstall(pkgmgr_client *pc, const char *pkg_type,
966                 const char *pkgid, const char *optional_file, pkgmgr_mode mode,
967                 pkgmgr_handler event_cb, void *data)
968 {
969         return pkgmgr_client_usr_reinstall(pc, pkg_type, pkgid, optional_file,
970                         mode, event_cb, data,GLOBAL_USER);
971 }
972
973 API int pkgmgr_client_usr_reinstall(pkgmgr_client * pc, const char *pkg_type,
974                 const char *pkgid, const char *optional_file, pkgmgr_mode mode,
975                 pkgmgr_handler event_cb, void *data, uid_t uid)
976 {
977         GVariant *result;
978         int ret = PKGMGR_R_ECOMM;
979         char *req_key = NULL;
980         int req_id;
981         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
982         char *pkgtype;
983         pkgmgrinfo_pkginfo_h handle;
984
985         if (pc == NULL || pkgid == NULL) {
986                 ERR("invalid parameter");
987                 return PKGMGR_R_EINVAL;
988         }
989
990         if (mpc->ctype != PC_REQUEST) {
991                 ERR("mpc->ctype is not PC_REQUEST");
992                 return PKGMGR_R_EINVAL;
993         }
994
995         ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &handle);
996         if (ret < 0)
997                 return PKGMGR_R_EINVAL;
998
999         ret = pkgmgrinfo_pkginfo_get_type(handle, &pkgtype);
1000         if (ret < 0) {
1001                 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1002                 return PKGMGR_R_ERROR;
1003         }
1004
1005         result = comm_client_request(mpc->info.request.cc, "reinstall",
1006                         g_variant_new("(uss)", uid, pkgtype, pkgid));
1007         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1008         if (result == NULL)
1009                 return PKGMGR_R_ECOMM;
1010         g_variant_get(result, "(i&s)", &ret, &req_key);
1011         if (req_key == NULL) {
1012                 g_variant_unref(result);
1013                 return PKGMGR_R_ECOMM;
1014         }
1015         if (ret != PKGMGR_R_OK) {
1016                 g_variant_unref(result);
1017                 return ret;
1018         }
1019
1020         req_id = _get_request_id();
1021         __add_op_cbinfo(mpc, req_id, req_key, event_cb, NULL, data);
1022
1023         g_variant_unref(result);
1024
1025         return req_id;
1026 }
1027
1028 API int pkgmgr_client_uninstall(pkgmgr_client *pc, const char *pkg_type,
1029                 const char *pkgid, pkgmgr_mode mode, pkgmgr_handler event_cb,
1030                 void *data)
1031 {
1032         return pkgmgr_client_usr_uninstall(pc, pkg_type,pkgid, mode, event_cb,
1033                         data, GLOBAL_USER);
1034 }
1035
1036 API int pkgmgr_client_usr_uninstall(pkgmgr_client *pc, const char *pkg_type,
1037                 const char *pkgid, pkgmgr_mode mode, pkgmgr_handler event_cb,
1038                 void *data, uid_t uid)
1039 {
1040         GVariant *result;
1041         int ret = PKGMGR_R_ECOMM;
1042         char *req_key = NULL;
1043         int req_id;
1044         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1045         char *pkgtype;
1046         pkgmgrinfo_pkginfo_h handle;
1047
1048         if (pc == NULL || pkgid == NULL) {
1049                 ERR("invalid parameter");
1050                 return PKGMGR_R_EINVAL;
1051         }
1052
1053         if (mpc->ctype != PC_REQUEST) {
1054                 ERR("mpc->ctype is not PC_REQUEST");
1055                 return PKGMGR_R_EINVAL;
1056         }
1057
1058         ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgid, uid, &handle);
1059         if (ret < 0)
1060                 return PKGMGR_R_EINVAL;
1061
1062         ret = pkgmgrinfo_pkginfo_get_type(handle, &pkgtype);
1063         if (ret < 0) {
1064                 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1065                 return PKGMGR_R_ERROR;
1066         }
1067
1068         /* TODO: check removable ? */
1069
1070         result = comm_client_request(mpc->info.request.cc, "uninstall",
1071                         g_variant_new("(uss)", uid, pkgtype, pkgid));
1072         if (result == NULL) {
1073                 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1074                 return PKGMGR_R_ECOMM;
1075         }
1076         g_variant_get(result, "(i&s)", &ret, &req_key);
1077         if (req_key == NULL) {
1078                 g_variant_unref(result);
1079                 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1080                 return PKGMGR_R_ECOMM;
1081         }
1082         if (ret != PKGMGR_R_OK) {
1083                 g_variant_unref(result);
1084                 pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1085                 return ret;
1086         }
1087
1088         req_id = _get_request_id();
1089         __add_op_cbinfo(mpc, req_id, req_key, event_cb, NULL, data);
1090
1091         g_variant_unref(result);
1092         pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
1093
1094         return req_id;
1095 }
1096
1097 API int pkgmgr_client_move(pkgmgr_client *pc, const char *pkg_type,
1098                 const char *pkgid, pkgmgr_move_type move_type, pkgmgr_mode mode)
1099 {
1100         return pkgmgr_client_usr_move(pc, pkg_type, pkgid, move_type, mode,
1101                         GLOBAL_USER);
1102 }
1103 API int pkgmgr_client_usr_move(pkgmgr_client *pc, const char *pkg_type,
1104                 const char *pkgid, pkgmgr_move_type move_type,
1105                 pkgmgr_mode mode, uid_t uid)
1106 {
1107         GVariant *result;
1108         int ret = PKGMGR_R_ECOMM;
1109         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1110
1111         if (pc == NULL || pkg_type == NULL || pkgid == NULL) {
1112                 ERR("invalid parameter");
1113                 return PKGMGR_R_EINVAL;
1114         }
1115
1116         if ((move_type < PM_MOVE_TO_INTERNAL) || (move_type > PM_MOVE_TO_SDCARD))
1117                 return PKGMGR_R_EINVAL;
1118
1119         if (mpc->ctype != PC_REQUEST) {
1120                 ERR("mpc->ctype is not PC_REQUEST");
1121                 return PKGMGR_R_EINVAL;
1122         }
1123
1124         result = comm_client_request(mpc->info.request.cc, "move",
1125                         g_variant_new("(uss)", uid, pkg_type, pkgid));
1126         if (result == NULL)
1127                 return PKGMGR_R_ECOMM;
1128         g_variant_get(result, "(i)", &ret);
1129         g_variant_unref(result);
1130
1131         return ret;
1132 }
1133
1134 API int pkgmgr_client_usr_activate(pkgmgr_client *pc, const char *pkg_type,
1135                 const char *pkgid, uid_t uid)
1136 {
1137         GVariant *result;
1138         int ret = PKGMGR_R_ECOMM;
1139         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1140
1141         if (pc == NULL || pkgid == NULL) {
1142                 ERR("invalid parameter");
1143                 return PKGMGR_R_EINVAL;
1144         }
1145
1146         result = comm_client_request(mpc->info.request.cc, "enable_pkg",
1147                         g_variant_new("(us)", uid, pkgid));
1148         if (result == NULL)
1149                 return PKGMGR_R_ECOMM;
1150         g_variant_get(result, "(i)", &ret);
1151         g_variant_unref(result);
1152
1153         return ret;
1154 }
1155
1156 API int pkgmgr_client_activate(pkgmgr_client *pc, const char *pkg_type,
1157                 const char *pkgid)
1158 {
1159         return pkgmgr_client_usr_activate(pc, pkg_type, pkgid, GLOBAL_USER);
1160 }
1161
1162 API int pkgmgr_client_usr_deactivate(pkgmgr_client *pc, const char *pkg_type,
1163                                  const char *pkgid, uid_t uid)
1164 {
1165         GVariant *result;
1166         int ret = PKGMGR_R_ECOMM;
1167         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1168
1169         if (pc == NULL || pkgid == NULL) {
1170                 ERR("invalid parameter");
1171                 return PKGMGR_R_EINVAL;
1172         }
1173
1174         result = comm_client_request(mpc->info.request.cc, "disable_pkg",
1175                         g_variant_new("(us)", uid, pkgid));
1176         if (result == NULL)
1177                 return PKGMGR_R_ECOMM;
1178         g_variant_get(result, "(i)", &ret);
1179         g_variant_unref(result);
1180
1181         return ret;
1182 }
1183
1184 API int pkgmgr_client_deactivate(pkgmgr_client *pc, const char *pkg_type,
1185                                  const char *pkgid)
1186 {
1187         return pkgmgr_client_usr_deactivate(pc, pkg_type, pkgid, GLOBAL_USER);
1188 }
1189
1190 API int pkgmgr_client_usr_activate_app(pkgmgr_client *pc, const char *appid,
1191                 uid_t uid)
1192 {
1193         GVariant *result;
1194         int ret = PKGMGR_R_ECOMM;
1195         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1196
1197         if (pc == NULL || appid == NULL) {
1198                 ERR("invalid parameter");
1199                 return PKGMGR_R_EINVAL;
1200         }
1201
1202         result = comm_client_request(mpc->info.request.cc, "enable_app",
1203                         g_variant_new("(us)", uid, appid));
1204         if (result == NULL)
1205                 return PKGMGR_R_ECOMM;
1206         g_variant_get(result, "(i)", &ret);
1207         g_variant_unref(result);
1208
1209         return ret;
1210 }
1211
1212 API int pkgmgr_client_activate_app(pkgmgr_client * pc, const char *appid)
1213 {
1214         return pkgmgr_client_usr_activate_app(pc, appid, GLOBAL_USER);
1215 }
1216
1217 /* TODO: deprecate? */
1218 API int pkgmgr_client_usr_activate_appv(pkgmgr_client *pc, const char *appid,
1219                 char *const argv[], uid_t uid)
1220 {
1221         return pkgmgr_client_usr_activate_app(pc, appid, uid);
1222 }
1223
1224 API int pkgmgr_client_activate_appv(pkgmgr_client *pc, const char *appid,
1225                 char *const argv[])
1226 {
1227         return pkgmgr_client_usr_activate_app(pc, appid, GLOBAL_USER);
1228 }
1229
1230 API int pkgmgr_client_usr_deactivate_app(pkgmgr_client *pc, const char *appid,
1231                 uid_t uid)
1232 {
1233         GVariant *result;
1234         int ret = PKGMGR_R_ECOMM;
1235         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1236
1237         if (pc == NULL || appid == NULL) {
1238                 ERR("invalid parameter");
1239                 return PKGMGR_R_EINVAL;
1240         }
1241
1242         result = comm_client_request(mpc->info.request.cc, "disable_app",
1243                         g_variant_new("(us)", uid, appid));
1244         if (result == NULL)
1245                 return PKGMGR_R_ECOMM;
1246         g_variant_get(result, "(i)", &ret);
1247         g_variant_unref(result);
1248
1249         return ret;
1250 }
1251
1252 API int pkgmgr_client_deactivate_app(pkgmgr_client *pc, const char *appid)
1253 {
1254         return pkgmgr_client_usr_deactivate_app(pc, appid, GLOBAL_USER);
1255 }
1256
1257 API int pkgmgr_client_usr_clear_user_data(pkgmgr_client *pc,
1258                 const char *pkg_type, const char *appid, pkgmgr_mode mode,
1259                 uid_t uid)
1260 {
1261         GVariant *result;
1262         int ret = PKGMGR_R_ECOMM;
1263         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1264
1265         if (pc == NULL || pkg_type == NULL || appid == NULL) {
1266                 ERR("invalid parameter");
1267                 return PKGMGR_R_EINVAL;
1268         }
1269
1270         if (mpc->ctype != PC_REQUEST) {
1271                 ERR("mpc->ctype is not PC_REQUEST");
1272                 return PKGMGR_R_EINVAL;
1273         }
1274
1275         result = comm_client_request(mpc->info.request.cc, "cleardata",
1276                         g_variant_new("(uss)", uid, pkg_type, appid));
1277         if (result == NULL)
1278                 return PKGMGR_R_ECOMM;
1279
1280         g_variant_get(result, "(i)", &ret);
1281         g_variant_unref(result);
1282
1283         return ret;
1284 }
1285
1286 API int pkgmgr_client_clear_user_data(pkgmgr_client *pc, const char *pkg_type,
1287                 const char *appid, pkgmgr_mode mode)
1288 {
1289         return pkgmgr_client_usr_clear_user_data(pc, pkg_type, appid, mode,
1290                         GLOBAL_USER);
1291 }
1292
1293 API int pkgmgr_client_set_status_type(pkgmgr_client *pc, int status_type)
1294 {
1295         int ret = -1;
1296
1297         retvm_if(pc == NULL, PKGMGR_R_EINVAL, "package manager client pc is NULL");
1298         retvm_if(status_type == PKGMGR_CLIENT_STATUS_ALL, PKGMGR_R_OK, "status_type is PKGMGR_CLIENT_STATUS_ALL");
1299         pkgmgr_client_t *mpc = (pkgmgr_client_t *) pc;
1300
1301         /*  free listening head */
1302         listen_cb_info *tmp = NULL;
1303         listen_cb_info *prev = NULL;
1304         for (tmp = mpc->info.listening.lhead; tmp;) {
1305                 prev = tmp;
1306                 tmp = tmp->next;
1307                 free(prev);
1308         }
1309
1310         /* free dbus connection */
1311         ret = comm_client_free(mpc->info.listening.cc);
1312         retvm_if(ret < 0, PKGMGR_R_ERROR, "comm_client_free() failed - %d", ret);
1313
1314         /* Manage pc for seperated event */
1315         mpc->ctype = PC_LISTENING;
1316         mpc->status_type = status_type;
1317
1318         mpc->info.listening.cc = comm_client_new();
1319         retvm_if(mpc->info.listening.cc == NULL, PKGMGR_R_EINVAL, "client creation failed");
1320
1321         if ((mpc->status_type & PKGMGR_CLIENT_STATUS_INSTALL) == PKGMGR_CLIENT_STATUS_INSTALL) {
1322                 ret = comm_client_set_status_callback(COMM_STATUS_BROADCAST_INSTALL, mpc->info.listening.cc, __status_callback, pc);
1323                 retvm_if(ret < 0, PKGMGR_R_ECOMM, "PKGMGR_CLIENT_STATUS_INSTALL failed - %d", ret);
1324         }
1325
1326         if ((mpc->status_type & PKGMGR_CLIENT_STATUS_UNINSTALL) == PKGMGR_CLIENT_STATUS_UNINSTALL) {
1327                 ret = comm_client_set_status_callback(COMM_STATUS_BROADCAST_UNINSTALL, mpc->info.listening.cc, __status_callback, pc);
1328                 retvm_if(ret < 0, PKGMGR_R_ECOMM, "COMM_STATUS_BROADCAST_UNINSTALL failed - %d", ret);
1329         }
1330
1331         if ((mpc->status_type & PKGMGR_CLIENT_STATUS_MOVE) == PKGMGR_CLIENT_STATUS_MOVE) {
1332                 ret = comm_client_set_status_callback(COMM_STATUS_BROADCAST_MOVE, mpc->info.listening.cc, __status_callback, pc);
1333                 retvm_if(ret < 0, PKGMGR_R_ECOMM, "COMM_STATUS_BROADCAST_MOVE failed - %d", ret);
1334         }
1335
1336         if ((mpc->status_type & PKGMGR_CLIENT_STATUS_INSTALL_PROGRESS) == PKGMGR_CLIENT_STATUS_INSTALL_PROGRESS) {
1337                 ret = comm_client_set_status_callback(COMM_STATUS_BROADCAST_INSTALL_PROGRESS, mpc->info.listening.cc, __status_callback, pc);
1338                 retvm_if(ret < 0, PKGMGR_R_ECOMM, "COMM_STATUS_BROADCAST_INSTALL_PROGRESS failed - %d", ret);
1339         }
1340
1341    if ((mpc->status_type & PKGMGR_CLIENT_STATUS_UPGRADE) == PKGMGR_CLIENT_STATUS_UPGRADE) {
1342            ret = comm_client_set_status_callback(COMM_STATUS_BROADCAST_UPGRADE, mpc->info.listening.cc, __status_callback, pc);
1343            retvm_if(ret < 0, PKGMGR_R_ECOMM, "COMM_STATUS_BROADCAST_UPGRADE failed - %d", ret);
1344    }
1345
1346    return PKGMGR_R_OK;
1347 }
1348
1349 API int pkgmgr_client_listen_status(pkgmgr_client *pc, pkgmgr_handler event_cb,
1350                                     void *data)
1351 {
1352         int req_id;
1353         /* Check for NULL value of pc */
1354         retvm_if(pc == NULL, PKGMGR_R_EINVAL, "package manager client pc is NULL");
1355         pkgmgr_client_t *mpc = (pkgmgr_client_t *) pc;
1356
1357         /* 0. check input */
1358         retvm_if(mpc->ctype != PC_LISTENING, PKGMGR_R_EINVAL, "ctype is not PC_LISTENING");
1359         retvm_if(event_cb == NULL, PKGMGR_R_EINVAL, "event_cb is NULL");
1360
1361         /* 1. get id */
1362         req_id = _get_request_id();
1363
1364         /* 2. add callback info to pkgmgr_client */
1365         __add_stat_cbinfo(mpc, req_id, event_cb, data);
1366         return req_id;
1367 }
1368
1369 API int pkgmgr_client_broadcast_status(pkgmgr_client *pc, const char *pkg_type,
1370                                        const char *pkgid, const char *key,
1371                                        const char *val)
1372 {
1373         /* client cannot broadcast signal */
1374         return PKGMGR_R_OK;
1375 }
1376
1377 API int pkgmgr_client_request_service(pkgmgr_request_service_type service_type, int service_mode,
1378                                   pkgmgr_client * pc, const char *pkg_type, const char *pkgid,
1379                               const char *custom_info, pkgmgr_handler event_cb, void *data)
1380 {
1381         return pkgmgr_client_usr_request_service(service_type, service_mode, pc, pkg_type, pkgid, GLOBAL_USER, custom_info, event_cb, data);
1382 }
1383
1384 API int pkgmgr_client_usr_request_service(pkgmgr_request_service_type service_type, int service_mode,
1385                                   pkgmgr_client * pc, const char *pkg_type, const char *pkgid, uid_t uid,
1386                               const char *custom_info, pkgmgr_handler event_cb, void *data)
1387 {
1388         int ret =0;
1389
1390         /* Check for NULL value of service type */
1391         retvm_if(service_type > PM_REQUEST_MAX, PKGMGR_R_EINVAL, "service type is not defined\n");
1392         retvm_if(service_type < 0, PKGMGR_R_EINVAL, "service type is error\n");
1393
1394         switch (service_type) {
1395         case PM_REQUEST_CSC:
1396                 tryvm_if(custom_info == NULL, ret = PKGMGR_R_EINVAL, "custom_info is NULL\n");
1397                 tryvm_if(strlen(custom_info) >= PKG_STRING_LEN_MAX, ret = PKGMGR_R_EINVAL, "optional_file over PKG_STRING_LEN_MAX");
1398                 tryvm_if(data == NULL, ret = PKGMGR_R_EINVAL, "data is NULL\n");
1399
1400                 ret = __csc_process(custom_info, (char *)data);
1401                 if (ret < 0)
1402                         ERR("__csc_process fail \n");
1403                 else
1404                         ret = PKGMGR_R_OK;
1405
1406                 break;
1407
1408         case PM_REQUEST_MOVE:
1409                 tryvm_if(pkgid == NULL, ret = PKGMGR_R_EINVAL, "pkgid is NULL\n");
1410                 tryvm_if(pc == NULL, ret = PKGMGR_R_EINVAL, "pc is NULL\n");
1411                 tryvm_if((service_mode < PM_MOVE_TO_INTERNAL) || (service_mode > PM_MOVE_TO_SDCARD), ret = PKGMGR_R_EINVAL, "service_mode is wrong\n");
1412
1413                 ret = __move_pkg_process(pc, pkgid, pkg_type, uid, (pkgmgr_move_type)service_mode, event_cb, data);
1414                 break;
1415
1416         case PM_REQUEST_GET_SIZE:
1417                 tryvm_if(pkgid == NULL, ret = PKGMGR_R_EINVAL, "pkgid is NULL\n");
1418                 tryvm_if(pc == NULL, ret = PKGMGR_R_EINVAL, "pc is NULL\n");
1419                 tryvm_if((service_mode < PM_GET_TOTAL_SIZE) || (service_mode >= PM_GET_MAX), ret = PKGMGR_R_EINVAL, "service_mode is wrong\n");
1420
1421                 ret = __get_size_process(pc, pkgid, uid, (pkgmgr_getsize_type)service_mode, event_cb, data);
1422                 break;
1423
1424         case PM_REQUEST_KILL_APP:
1425         case PM_REQUEST_CHECK_APP:
1426                 tryvm_if(pkgid == NULL, ret = PKGMGR_R_EINVAL, "pkgid is NULL\n");
1427                 tryvm_if(pc == NULL, ret = PKGMGR_R_EINVAL, "pc is NULL\n");
1428
1429                 ret = __check_app_process(service_type, pc, pkgid, uid, data);
1430                 if (ret < 0)
1431                         ERR("__check_app_process fail \n");
1432                 else
1433                         ret = PKGMGR_R_OK;
1434
1435                 break;
1436
1437         default:
1438                 ERR("Wrong Request\n");
1439                 ret = -1;
1440                 break;
1441         }
1442
1443 catch:
1444
1445         return ret;
1446 }
1447
1448
1449 API int pkgmgr_client_usr_request_size_info(uid_t uid)
1450 {
1451         int ret = 0;
1452         pkgmgr_client *pc = NULL;
1453
1454         pc = pkgmgr_client_new(PC_REQUEST);
1455         retvm_if(pc == NULL, PKGMGR_R_EINVAL, "request pc is null\n");
1456
1457         ret = __request_size_info(pc, uid);
1458         if (ret < 0) {
1459                 ERR("__request_size_info fail \n");
1460         }
1461
1462         pkgmgr_client_free(pc);
1463         return ret;
1464 }
1465
1466 API int pkgmgr_client_request_size_info(void) // get all package size (data, total)
1467 {
1468         return pkgmgr_client_usr_request_size_info(GLOBAL_USER);
1469 }
1470
1471 API int pkgmgr_client_usr_clear_cache_dir(const char *pkgid, uid_t uid)
1472 {
1473         GVariant *result;
1474         int ret = PKGMGR_R_ECOMM;
1475         pkgmgr_client_t *pc;
1476
1477         if (pkgid == NULL) {
1478                 ERR("invalid parameter");
1479                 return PKGMGR_R_EINVAL;
1480         }
1481
1482         pc = pkgmgr_client_new(PC_REQUEST);
1483         if (pc == NULL) {
1484                 ERR("out of memory");
1485                 return PKGMGR_R_ESYSTEM;
1486         }
1487
1488         result = comm_client_request(pc->info.request.cc, "clearcache",
1489                         g_variant_new("(s)", pkgid));
1490         if (result == NULL)
1491                 return PKGMGR_R_ECOMM;
1492         g_variant_get(result, "(i)", &ret);
1493         g_variant_unref(result);
1494
1495         return ret;
1496 }
1497
1498 API int pkgmgr_client_clear_cache_dir(const char *pkgid)
1499 {
1500         return pkgmgr_client_usr_clear_cache_dir(pkgid, GLOBAL_USER);
1501 }
1502
1503 API int pkgmgr_client_clear_usr_all_cache_dir(uid_t uid)
1504 {
1505         return pkgmgr_client_usr_clear_cache_dir(PKG_CLEAR_ALL_CACHE, uid);
1506 }
1507
1508 API int pkgmgr_client_clear_all_cache_dir(void)
1509 {
1510         return pkgmgr_client_usr_clear_cache_dir(PKG_CLEAR_ALL_CACHE, GLOBAL_USER);
1511 }
1512
1513 API int pkgmgr_client_get_size(pkgmgr_client * pc, const char *pkgid,
1514                 pkgmgr_getsize_type get_type, pkgmgr_handler event_cb,
1515                 void *data)
1516 {
1517         return pkgmgr_client_usr_get_size(pc, pkgid, get_type, event_cb, data,
1518                         GLOBAL_USER);
1519 }
1520
1521 API int pkgmgr_client_usr_get_size(pkgmgr_client * pc, const char *pkgid,
1522                 pkgmgr_getsize_type get_type, pkgmgr_handler event_cb,
1523                 void *data, uid_t uid)
1524 {
1525         GVariant *result;
1526         int ret = PKGMGR_R_ECOMM;
1527         char *req_key = NULL;
1528         int req_id;
1529         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1530
1531         if (pc == NULL || pkgid == NULL || event_cb == NULL) {
1532                 ERR("invalid parameter");
1533                 return PKGMGR_R_EINVAL;
1534         }
1535
1536         if (mpc->ctype != PC_REQUEST) {
1537                 ERR("mpc->ctype is not PC_REQUEST");
1538                 return PKGMGR_R_EINVAL;
1539         }
1540
1541         /* FIXME */
1542         if (strcmp(pkgid, PKG_SIZE_INFO_TOTAL) == 0)
1543                 get_type = PM_GET_TOTAL_PKG_SIZE_INFO;
1544         else
1545                 get_type = PM_GET_PKG_SIZE_INFO;
1546         result = comm_client_request(mpc->info.request.cc, "getsize",
1547                         g_variant_new("(usi)", uid, pkgid, get_type));
1548         if (result == NULL)
1549                 return PKGMGR_R_ECOMM;
1550
1551         g_variant_get(result, "(i&s)", &ret, &req_key);
1552         if (req_key == NULL) {
1553                 g_variant_unref(result);
1554                 return PKGMGR_R_ECOMM;
1555         }
1556         if (ret != PKGMGR_R_OK) {
1557                 g_variant_unref(result);
1558                 return ret;
1559         }
1560
1561         req_id = _get_request_id();
1562         __add_op_cbinfo(mpc, req_id, req_key, event_cb, NULL, data);
1563
1564         g_variant_unref(result);
1565
1566         return PKGMGR_R_OK;
1567 }
1568
1569 API int pkgmgr_client_usr_get_package_size_info(pkgmgr_client *pc,
1570                 const char *pkgid, pkgmgr_pkg_size_info_receive_cb event_cb,
1571                 void *user_data, uid_t uid)
1572 {
1573         GVariant *result;
1574         int ret = PKGMGR_R_ECOMM;
1575         char *req_key = NULL;
1576         int req_id;
1577         int get_type;
1578         pkgmgr_client_t *mpc = (pkgmgr_client_t *)pc;
1579
1580         if (pc == NULL || pkgid == NULL || event_cb == NULL) {
1581                 ERR("invalid parameter");
1582                 return PKGMGR_R_EINVAL;
1583         }
1584
1585         if (mpc->ctype != PC_REQUEST) {
1586                 ERR("mpc->ctype is not PC_REQUEST");
1587                 return PKGMGR_R_EINVAL;
1588         }
1589
1590         /* FIXME */
1591         if (__change_op_cb_for_getsize(mpc) < 0) {
1592                 ERR("__change_op_cb_for_getsize failed");
1593                 return PKGMGR_R_ESYSTEM;
1594         }
1595
1596         if (strcmp(pkgid, PKG_SIZE_INFO_TOTAL) == 0)
1597                 get_type = PM_GET_TOTAL_PKG_SIZE_INFO;
1598         else
1599                 get_type = PM_GET_PKG_SIZE_INFO;
1600         result = comm_client_request(mpc->info.request.cc, "getsize",
1601                         g_variant_new("(usi)", uid, pkgid, get_type));
1602         if (result == NULL)
1603                 return PKGMGR_R_ECOMM;
1604
1605         g_variant_get(result, "(i&s)", &ret, &req_key);
1606         if (req_key == NULL) {
1607                 g_variant_unref(result);
1608                 return PKGMGR_R_ECOMM;
1609         }
1610         if (ret != PKGMGR_R_OK) {
1611                 g_variant_unref(result);
1612                 return ret;
1613         }
1614
1615         req_id = _get_request_id();
1616         __add_op_cbinfo(mpc, req_id, req_key, __get_pkg_size_info_cb, event_cb,
1617                         user_data);
1618
1619         g_variant_unref(result);
1620
1621         return PKGMGR_R_OK;
1622 }
1623
1624 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)
1625 {
1626         return pkgmgr_client_usr_get_package_size_info(pc, pkgid, event_cb, user_data, GLOBAL_USER);
1627 }
1628
1629 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)
1630 {       // total package size info
1631         return pkgmgr_client_usr_get_package_size_info(pc, PKG_SIZE_INFO_TOTAL, (pkgmgr_pkg_size_info_receive_cb)event_cb, user_data, uid);
1632 }
1633
1634 API int pkgmgr_client_get_total_package_size_info(pkgmgr_client *pc, pkgmgr_total_pkg_size_info_receive_cb event_cb, void *user_data)
1635 {
1636         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);
1637 }