d1278d3d19c2775ab9223325681a950a4730e3df
[platform/core/appfw/slp-pkgmgr.git] / installer / pkgmgr_installer.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 <unistd.h>
26 #include <string.h>
27 #include <errno.h>
28 #include <getopt.h>
29 #include <sys/types.h>
30 #include <sys/socket.h>
31 #include <sys/un.h>
32
33 #include <glib.h>
34 #include <gio/gio.h>
35 #include <tzplatform_config.h>
36
37 #include "pkgmgr_installer.h"
38 #include "pkgmgr_installer_config.h"
39 #include "pkgmgr_installer_debug.h"
40 #include "pkgmgr_installer_info.h"
41 #include "pkgmgr_installer_error.h"
42
43 #include <pkgmgr-info.h>
44
45 /* API export macro */
46 #ifndef API
47 #define API __attribute__ ((visibility("default")))
48 #endif
49
50 #define MAX_STRLEN 1024
51 #define MAX_QUERY_LEN   4096
52
53 #define CHK_PI_RET(r) \
54         do { if (NULL == pi) return (r); } while (0)
55
56 #define OPTVAL_PRELOAD 1000
57 #define OPTVAL_FORCE_REMOVAL 1001
58 #define OPTVAL_PRELOAD_RW 1002
59 #define OPTVAL_NO_REMOVAL 1003
60 #define OPTVAL_KEEP_RWDATA 1004
61 #define OPTVAL_PARTIAL_RW 1005
62 #define OPTVAL_MIGRATE_EXTIMG 1006
63 #define OPTVAL_SKIP_CHECK_REFERENCE 1007
64 #define OPTVAL_RECOVER_DB 1008
65
66 /* Supported options */
67 const char *short_opts = "k:l:i:d:c:m:t:o:r:p:s:b:e:M:y:u:w:D:A:qGS";
68 const struct option long_opts[] = {
69         { "session-id", 1, NULL, 'k' },
70         { "license-path", 1, NULL, 'l' },
71         { "install", 1, NULL, 'i' },
72         { "uninstall", 1, NULL, 'd' },
73         { "clear", 1, NULL, 'c' },
74         { "move", 1, NULL, 'm' },
75         { "move-type", 1, NULL, 't' },
76         { "optional-data", 0, NULL, 'o' },
77         { "reinstall", 0, NULL, 'r' },
78         { "caller-pkgid", 1, NULL, 'p' },
79         { "tep-path", 1, NULL, 'e' },
80         { "tep-move", 1, NULL, 'M' },
81         { "smack", 1, NULL, 's' },
82         { "manifest-direct-install", 1, NULL, 'y' },
83         { "mount-install", 1, NULL, 'w' },
84         { "recovery", 1, NULL, 'b' },
85         { "debug-mode", 0, NULL, 'G' },
86         { "skip-optimization", 0, NULL, 'S' },
87         { "preload", 0, NULL, OPTVAL_PRELOAD }, /* for preload RO */
88         { "force-remove", 0, NULL, OPTVAL_FORCE_REMOVAL }, /* for preload RO/RW */
89         { "preload-rw", 0, NULL, OPTVAL_PRELOAD_RW }, /* for preload RW */
90         { "no-remove", 0, NULL, OPTVAL_NO_REMOVAL }, /* for preload RW */
91         { "keep-rwdata", 0, NULL, OPTVAL_KEEP_RWDATA }, /* for preload RW */
92         { "partial-rw", 0, NULL, OPTVAL_PARTIAL_RW }, /* for preload RO */
93         { "migrate-extimg", 1, NULL, OPTVAL_MIGRATE_EXTIMG },
94         { "skip-check-reference", 0, NULL, OPTVAL_SKIP_CHECK_REFERENCE },
95         { "recover-db", 1, NULL, OPTVAL_RECOVER_DB },
96         { 0, 0, 0, 0 }  /* sentinel */
97 };
98
99 struct pkgmgr_installer {
100         int request_type;
101         int move_type;
102         char *pkgmgr_info;
103         char *session_id;
104         char *license_path;
105         char *optional_data;
106         char *caller_pkgid;
107         uid_t target_uid;
108         char *tep_path;
109         int tep_move;
110         int is_tep_included;
111         int is_preload;
112         int force_removal;
113         int is_preload_rw;
114         int no_removal;
115         int keep_rwdata;
116         int partial_rw;
117         int debug_mode;
118         int skip_check_reference;
119         int skip_optimization;
120         GDBusConnection *conn;
121         GHashTable *pkg_list;
122         GList *pkgs;
123 };
124
125 typedef struct pkg_signal_info {
126         char *pkgid;
127         char *pkg_type;
128 } pkg_signal_info;
129
130 static uid_t g_target_uid;
131 static int g_debug_mode;
132 static int g_skip_optimization;
133 static pkgmgr_privilege_level g_privilege_level = PM_PRIVILEGE_UNKNOWN;
134
135 static const char *__get_signal_name(pkgmgr_installer *pi, const char *key,
136                 const char *pkg_type)
137 {
138         if (strcmp(key, PKGMGR_INSTALLER_INSTALL_PERCENT_KEY_STR) == 0)
139                 return key;
140         else if (strcmp(key, PKGMGR_INSTALLER_GET_SIZE_KEY_STR) == 0)
141                 return key;
142         else if (strcmp(key, PKGMGR_INSTALLER_APPID_KEY_STR) == 0)
143                 return PKGMGR_INSTALLER_UNINSTALL_EVENT_STR;
144         else if (strcmp(pkg_type, PKGMGR_INSTALLER_CLEAR_CACHE_KEY_STR) == 0)
145                 return pkg_type;
146
147         switch (pi->request_type) {
148         case PKGMGR_REQ_INSTALL:
149         case PKGMGR_REQ_MANIFEST_DIRECT_INSTALL:
150         case PKGMGR_REQ_MOUNT_INSTALL:
151         case PKGMGR_REQ_REINSTALL:
152         case PKGMGR_REQ_ENABLE_PKG:
153         case PKGMGR_REQ_RECOVER:
154                 return PKGMGR_INSTALLER_INSTALL_EVENT_STR;
155         case PKGMGR_REQ_UNINSTALL:
156         case PKGMGR_REQ_DISABLE_PKG:
157                 return PKGMGR_INSTALLER_UNINSTALL_EVENT_STR;
158         case PKGMGR_REQ_UPGRADE:
159                 return PKGMGR_INSTALLER_UPGRADE_EVENT_STR;
160         case PKGMGR_REQ_MOVE:
161                 return PKGMGR_INSTALLER_MOVE_EVENT_STR;
162         case PKGMGR_REQ_ENABLE_APP:
163                 return PKGMGR_INSTALLER_APP_ENABLE_EVENT_STR;
164         case PKGMGR_REQ_DISABLE_APP:
165                 return PKGMGR_INSTALLER_APP_DISABLE_EVENT_STR;
166         case PKGMGR_REQ_ENABLE_APP_SPLASH_SCREEN:
167                 return PKGMGR_INSTALLER_APP_ENABLE_SPLASH_SCREEN_EVENT_STR;
168         case PKGMGR_REQ_DISABLE_APP_SPLASH_SCREEN:
169                 return PKGMGR_INSTALLER_APP_DISABLE_SPLASH_SCREEN_EVENT_STR;
170         case PKGMGR_REQ_CLEAR:
171                 return PKGMGR_INSTALLER_CLEAR_EVENT_STR;
172         case PKGMGR_REQ_GETSIZE:
173                 return PKGMGR_INSTALLER_GET_SIZE_KEY_STR;
174         }
175
176         ERR("cannot find type");
177
178         return NULL;
179 }
180
181 static int __send_signal_for_event(pkgmgr_installer *pi, const char *pkg_type,
182                 const char *pkgid, const char *appid, const char *key,
183                 const char *val)
184 {
185         char *sid;
186         const char *tmp_appid = appid;
187         const char *signal_name;
188         GVariant *v;
189         GVariantBuilder *builder;
190         GError *err = NULL;
191
192         if (!pi || pi->conn == NULL)
193                 return -1;
194
195         sid = pi->session_id;
196         if (!sid)
197                 sid = "";
198
199         signal_name = __get_signal_name(pi, key, pkg_type);
200         if (!signal_name) {
201                 ERR("unknown signal type");
202                 return -1;
203         }
204
205         builder = g_variant_builder_new(G_VARIANT_TYPE("a(sss)"));
206         g_variant_builder_add(builder, "(sss)", pkgid,
207                         (tmp_appid ? tmp_appid : ""), pkg_type);
208         v = g_variant_new("(usa(sss)ss)",
209                         pi->target_uid, sid, builder, key, val);
210         g_variant_builder_unref(builder);
211         if (g_dbus_connection_emit_signal(pi->conn, NULL,
212                                 PKGMGR_INSTALLER_DBUS_OBJECT_PATH,
213                                 PKGMGR_INSTALLER_DBUS_INTERFACE, signal_name,
214                                 v, &err) != TRUE) {
215                 ERR("failed to send dbus signal");
216                 if (err) {
217                         ERR("err: %s", err->message);
218                         g_error_free(err);
219                 }
220                 return -1;
221         }
222
223         return 0;
224 }
225
226 static int __send_signal_to_agent(uid_t uid, void *data, size_t len)
227 {
228         int fd;
229         struct sockaddr_un sa;
230         int r;
231
232         fd = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0);
233         if (fd == -1) {
234                 ERR("failed to create socket: %d", errno);
235                 return -1;
236         }
237
238         sa.sun_family = AF_UNIX;
239         snprintf(sa.sun_path, sizeof(sa.sun_path), "/run/pkgmgr/agent/%d", uid);
240
241         r = connect(fd, (struct sockaddr *)&sa, sizeof(sa));
242         if (r == -1) {
243                 ERR("failed to connect socket(%s): %d", sa.sun_path, errno);
244                 close(fd);
245                 return -1;
246         }
247
248         r = send(fd, data, len, MSG_NOSIGNAL);
249         if (r < 0) {
250                 ERR("failed to send data: %d", errno);
251                 close(fd);
252                 return -1;
253         }
254
255         close(fd);
256
257         return 0;
258 }
259
260 static int __send_signal_for_event_for_uid(pkgmgr_installer *pi, uid_t uid,
261                 const char *pkg_type, const char *pkgid, const char *appid,
262                 const char *key, const char *val)
263 {
264         char *sid;
265         const char *signal_name;
266         const char *tmp_appid = appid;
267         size_t name_size;
268         GVariantBuilder *builder;
269         GVariant *gv;
270         gsize gv_len;
271         gpointer gv_data;
272         void *data;
273         void *ptr;
274         size_t data_len;
275
276         if (!pi || pi->conn == NULL)
277                 return -1;
278
279         sid = pi->session_id;
280         if (!sid)
281                 sid = "";
282
283         data_len = sizeof(size_t) + sizeof(gsize);
284
285         signal_name = __get_signal_name(pi, key, pkg_type);
286         if (!signal_name) {
287                 ERR("unknown signal name");
288                 return -1;
289         }
290
291         /* including null byte */
292         name_size = strlen(signal_name) + 1;
293         data_len += name_size;
294
295         builder = g_variant_builder_new(G_VARIANT_TYPE("a(sss)"));
296         g_variant_builder_add(builder, "(sss)", pkgid,
297                         (tmp_appid ? tmp_appid : ""), pkg_type);
298         gv = g_variant_new("(usa(sss)ss)", pi->target_uid, sid,
299                         builder, key, val);
300         g_variant_builder_unref(builder);
301         if (gv == NULL) {
302                 ERR("failed to create GVariant instance");
303                 return -1;
304         }
305         gv_len = g_variant_get_size(gv);
306         gv_data = g_malloc(gv_len);
307         g_variant_store(gv, gv_data);
308         g_variant_unref(gv);
309         data_len += gv_len;
310
311         data = malloc(data_len);
312         if (data == NULL) {
313                 ERR("out of memory");
314                 g_free(gv_data);
315                 return -1;
316         }
317         ptr = data;
318         memcpy(ptr, &name_size, sizeof(size_t));
319         ptr += sizeof(size_t);
320         memcpy(ptr, &gv_len, sizeof(gsize));
321         ptr += sizeof(gsize);
322         memcpy(ptr, signal_name, name_size);
323         ptr += name_size;
324         memcpy(ptr, gv_data, gv_len);
325         g_free(gv_data);
326
327         if (__send_signal_to_agent(uid, data, data_len)) {
328                 ERR("failed to send signal to agent");
329                 free(data);
330                 return -1;
331         }
332
333         free(data);
334
335         return 0;
336 }
337
338 static void __free_pkg_list(gpointer data)
339 {
340         pkg_signal_info *info = (pkg_signal_info *)data;
341         free(info->pkgid);
342         free(info->pkg_type);
343         free(info);
344 }
345
346 API pkgmgr_installer *pkgmgr_installer_new(void)
347 {
348         pkgmgr_installer *pi;
349         GError *err = NULL;
350
351         pi = calloc(1, sizeof(struct pkgmgr_installer));
352         if (pi == NULL)
353                 return NULL;
354
355         pi->conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
356         if (pi->conn == NULL) {
357                 ERR("failed to get bus: %s", err->message);
358                 g_error_free(err);
359                 free(pi);
360                 return NULL;
361         }
362
363         pi->tep_path = NULL;
364         pi->tep_move = 0;
365         pi->request_type = PKGMGR_REQ_INVALID;
366         pi->pkg_list = g_hash_table_new_full(
367                         g_str_hash, g_str_equal, NULL, __free_pkg_list);
368         return pi;
369 }
370
371 API pkgmgr_installer *pkgmgr_installer_offline_new(void)
372 {
373         pkgmgr_installer *pi;
374
375         pi = calloc(1, sizeof(struct pkgmgr_installer));
376         if (pi == NULL)
377                 return NULL;
378
379         pi->tep_path = NULL;
380         pi->tep_move = 0;
381         pi->request_type = PKGMGR_REQ_INVALID;
382
383         return pi;
384 }
385
386 API int pkgmgr_installer_free(pkgmgr_installer *pi)
387 {
388         CHK_PI_RET(-EINVAL);
389
390         /* free members */
391         if (pi->pkgmgr_info)
392                 free(pi->pkgmgr_info);
393         if (pi->session_id)
394                 free(pi->session_id);
395         if (pi->optional_data)
396                 free(pi->optional_data);
397         if (pi->caller_pkgid)
398                 free(pi->caller_pkgid);
399         if (pi->tep_path)
400                 free(pi->tep_path);
401
402         if (pi->conn) {
403                 g_dbus_connection_flush_sync(pi->conn, NULL, NULL);
404                 g_object_unref(pi->conn);
405         }
406
407         if (pi->pkg_list)
408                 g_hash_table_destroy(pi->pkg_list);
409
410         free(pi);
411
412         return 0;
413 }
414
415 static void __parse_multiple_pkgs(pkgmgr_installer *pi, int argc, char **argv)
416 {
417         while ((optind <= argc) && (*argv[optind - 1] != '-')) {
418                 pi->pkgs = g_list_append(pi->pkgs, strdup(argv[optind - 1]));
419                 optind++;
420         }
421         optind--;
422 }
423
424 API int
425 pkgmgr_installer_receive_request(pkgmgr_installer *pi,
426                                  const int argc, char **argv)
427 {
428         CHK_PI_RET(-EINVAL);
429
430         int r = 0;
431
432         /* Parse argv */
433         optind = 1;             /* Initialize optind to clear prev. index */
434         int opt_idx = 0;
435         int c;
436         int mode = 0;
437
438         pi->target_uid = getuid();
439         g_target_uid = pi->target_uid;
440         g_debug_mode = 0;
441         g_skip_optimization = 0;
442
443         if (pi->pkgs) {
444                 g_list_free_full(pi->pkgs, free);
445                 pi->pkgs = NULL;
446         }
447
448         while (1) {
449                 c = getopt_long(argc, argv, short_opts, long_opts, &opt_idx);
450                 /* printf("c=%d %c\n", c, c); //debug */
451                 if (-1 == c)
452                         break;  /* Parse is end */
453                 switch (c) {
454                 case OPTVAL_PRELOAD:    /* request for preload app */
455                         pi->is_preload = 1;
456                         DBG("preload request [%d]", pi->is_preload);
457                         break;
458                 case OPTVAL_FORCE_REMOVAL:      /* request for force-remove */
459                         pi->force_removal = 1;
460                         DBG("force-remove request [%d]", pi->force_removal);
461                         break;
462                 case OPTVAL_PRELOAD_RW: /* request for preload-rw app */
463                         pi->is_preload_rw = 1;
464                         DBG("preload-rw request [%d]", pi->is_preload_rw);
465                         break;
466                 case OPTVAL_NO_REMOVAL: /* request for no-remove */
467                         pi->no_removal = 1;
468                         DBG("no-remove request [%d]", pi->no_removal);
469                         break;
470                 case OPTVAL_KEEP_RWDATA:        /* request for keep-rwdata */
471                         pi->keep_rwdata = 1;
472                         DBG("keep-rwdata request [%d]", pi->keep_rwdata);
473                         break;
474                 case OPTVAL_PARTIAL_RW: /* request for partial-rw */
475                         pi->partial_rw = 1;
476                         DBG("partial-rw request [%d]", pi->partial_rw);
477                         break;
478                 case OPTVAL_MIGRATE_EXTIMG:
479                         /* request for legacy extimg migration */
480                         if (mode) {
481                                 r = -EINVAL;
482                                 goto RET;
483                         }
484                         mode = OPTVAL_MIGRATE_EXTIMG;
485                         pi->request_type = PKGMGR_REQ_MIGRATE_EXTIMG;
486                         if (pi->pkgmgr_info)
487                                 free(pi->pkgmgr_info);
488                         pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
489                         __parse_multiple_pkgs(pi, argc, argv);
490                         DBG("legacy extimg migration requested");
491                         break;
492                 case OPTVAL_SKIP_CHECK_REFERENCE:
493                         pi->skip_check_reference = 1;
494                         break;
495                 case OPTVAL_RECOVER_DB:
496                         pi->request_type = PKGMGR_REQ_RECOVER_DB;
497                         pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
498                         __parse_multiple_pkgs(pi, argc, argv);
499                         break;
500                 case 'k':       /* session id */
501                         if (pi->session_id)
502                                 free(pi->session_id);
503                         pi->session_id = strndup(optarg, MAX_STRLEN);
504                         break;
505
506                 case 'l':       /* license path */
507                         if (pi->license_path)
508                                 free(pi->license_path);
509                         pi->license_path = strndup(optarg, MAX_STRLEN);
510                         break;
511
512                 case 'i':       /* install */
513                         if (mode) {
514                                 r = -EINVAL;
515                                 goto RET;
516                         }
517                         mode = 'i';
518                         pi->request_type = PKGMGR_REQ_INSTALL;
519                         if (pi->pkgmgr_info)
520                                 free(pi->pkgmgr_info);
521                         pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
522                         __parse_multiple_pkgs(pi, argc, argv);
523                         DBG("option is [i] pkgid[%s]", pi->pkgmgr_info);
524                         if (pi->pkgmgr_info && strlen(pi->pkgmgr_info) == 0) {
525                                 free(pi->pkgmgr_info);
526                                 pi->pkgmgr_info = NULL;
527                         } else {
528                                 mode = 'i';
529                         }
530                         break;
531
532                 case 'e':       /* install */
533                         if (pi->tep_path)
534                                 free(pi->tep_path);
535                         pi->tep_path = strndup(optarg, MAX_STRLEN);
536                         pi->is_tep_included = 1;
537                         DBG("option is [e] tep_path[%s]", pi->tep_path);
538                         break;
539
540                 case 'M':       /* install */
541                         if (strcmp(optarg, "tep_move") == 0)
542                                 pi->tep_move = 1;
543                         else
544                                 pi->tep_move = 0;
545                         DBG("option is [M] tep_move[%d]", pi->tep_move);
546                         break;
547
548                 case 'd':       /* uninstall */
549                         if (mode) {
550                                 r = -EINVAL;
551                                 goto RET;
552                         }
553                         mode = 'd';
554                         pi->request_type = PKGMGR_REQ_UNINSTALL;
555                         if (pi->pkgmgr_info)
556                                 free(pi->pkgmgr_info);
557                         pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
558                         __parse_multiple_pkgs(pi, argc, argv);
559                         break;
560
561
562                 case 'c':       /* clear */
563                         if (mode) {
564                                 r = -EINVAL;
565                                 goto RET;
566                         }
567                         mode = 'c';
568                         pi->request_type = PKGMGR_REQ_CLEAR;
569                         if (pi->pkgmgr_info)
570                                 free(pi->pkgmgr_info);
571                         pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
572                         __parse_multiple_pkgs(pi, argc, argv);
573                         break;
574
575                 case 'm':       /* move */
576                         if (mode) {
577                                 r = -EINVAL;
578                                 goto RET;
579                         }
580                         mode = 'm';
581                         pi->request_type = PKGMGR_REQ_MOVE;
582                         if (pi->pkgmgr_info)
583                                 free(pi->pkgmgr_info);
584                         pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
585                         __parse_multiple_pkgs(pi, argc, argv);
586                         break;
587
588                 case 'r':       /* reinstall */
589                         if (mode) {
590                                 r = -EINVAL;
591                                 goto RET;
592                         }
593                         mode = 'r';
594                         pi->request_type = PKGMGR_REQ_REINSTALL;
595                         if (pi->pkgmgr_info)
596                                 free(pi->pkgmgr_info);
597                         pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
598                         __parse_multiple_pkgs(pi, argc, argv);
599                         break;
600
601                 case 't': /* move type*/
602                         pi->move_type = atoi(optarg);
603                         break;
604
605                 case 'p': /* caller pkgid*/
606                         if (pi->caller_pkgid)
607                                 free(pi->caller_pkgid);
608                         pi->caller_pkgid = strndup(optarg, MAX_STRLEN);
609
610                         break;
611
612                 case 's':       /* smack */
613                         if (mode) {
614                                 r = -EINVAL;
615                                 goto RET;
616                         }
617                         mode = 's';
618                         pi->request_type = PKGMGR_REQ_SMACK;
619                         if (pi->pkgmgr_info)
620                                 free(pi->pkgmgr_info);
621                         pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
622                         __parse_multiple_pkgs(pi, argc, argv);
623                         break;
624
625                 case 'o': /* optional data*/
626                         pi->optional_data = strndup(optarg, MAX_STRLEN);
627                         break;
628
629                 case 'y': /* pkgid for direct manifest installation */
630                         mode = 'y';
631                         pi->request_type = PKGMGR_REQ_MANIFEST_DIRECT_INSTALL;
632                         pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
633                         __parse_multiple_pkgs(pi, argc, argv);
634                         break;
635
636                 case 'w': /* pkgid for mount installation */
637                         mode = 'w';
638                         pi->request_type = PKGMGR_REQ_MOUNT_INSTALL;
639                         pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
640                         __parse_multiple_pkgs(pi, argc, argv);
641                         break;
642
643                 case 'b': /* recovery */
644                         if (mode) {
645                                 r = -EINVAL;
646                                 goto RET;
647                         }
648                         mode = 'b';
649                         pi->request_type = PKGMGR_REQ_RECOVER;
650                         if (pi->pkgmgr_info)
651                                 free(pi->pkgmgr_info);
652                         pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
653                         __parse_multiple_pkgs(pi, argc, argv);
654                         break;
655
656                 case 'D': /* disable pkg */
657                         pi->request_type = PKGMGR_REQ_DISABLE_PKG;
658                         if (pi->pkgmgr_info)
659                                 free(pi->pkgmgr_info);
660                         pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
661                         __parse_multiple_pkgs(pi, argc, argv);
662                         break;
663
664                 case 'A': /* enable pkg */
665                         pi->request_type = PKGMGR_REQ_ENABLE_PKG;
666                         if (pi->pkgmgr_info)
667                                 free(pi->pkgmgr_info);
668                         pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
669                         __parse_multiple_pkgs(pi, argc, argv);
670                         break;
671
672                 case 'u': /* uid */
673                         g_target_uid = (uid_t)atoi(optarg);
674                         pi->target_uid = (uid_t)atoi(optarg);
675                         break;
676
677                 case 'G': /* debug mode */
678                         pi->debug_mode = 1;
679                         g_debug_mode = 1;
680                         break;
681
682                 case 'S': /* skip optimization */
683                         pi->skip_optimization = 1;
684                         g_skip_optimization = 1;
685                         break;
686
687                         /* Otherwise */
688                 case '?':       /* Not an option */
689                         break;
690
691                 case ':':       /* */
692                         break;
693
694                 }
695         }
696
697         /* if target user is not set, set as tizenglobalapp user */
698         if (pi->target_uid == 0) {
699                 pi->target_uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
700                 g_target_uid = pi->target_uid;
701         }
702  RET:
703         return r;
704 }
705
706 API int pkgmgr_installer_get_request_type(pkgmgr_installer *pi)
707 {
708         CHK_PI_RET(PKGMGR_REQ_INVALID);
709         return pi->request_type;
710 }
711
712 API uid_t pkgmgr_installer_get_uid(pkgmgr_installer *pi)
713 {
714         CHK_PI_RET(PKGMGR_REQ_INVALID);
715         return pi->target_uid;
716 }
717
718 API const char *pkgmgr_installer_get_request_info(pkgmgr_installer *pi)
719 {
720         CHK_PI_RET(PKGMGR_REQ_INVALID);
721         return pi->pkgmgr_info;
722 }
723
724 API const char *pkgmgr_installer_get_request_info_at(pkgmgr_installer *pi,
725                 int at)
726 {
727         CHK_PI_RET(PKGMGR_REQ_INVALID);
728         return (const char *)g_list_nth_data(pi->pkgs, at);
729 }
730
731 API int pkgmgr_installer_get_request_info_count(pkgmgr_installer *pi)
732 {
733         CHK_PI_RET(PKGMGR_REQ_INVALID);
734         return g_list_length(pi->pkgs);
735 }
736
737 API const char *pkgmgr_installer_get_tep_path(pkgmgr_installer *pi)
738 {
739         CHK_PI_RET(PKGMGR_REQ_INVALID);
740         return pi->tep_path;
741 }
742
743 API int pkgmgr_installer_get_tep_move_type(pkgmgr_installer *pi)
744 {
745         CHK_PI_RET(PKGMGR_REQ_INVALID);
746         return pi->tep_move;
747 }
748
749 API const char *pkgmgr_installer_get_session_id(pkgmgr_installer *pi)
750 {
751         CHK_PI_RET(PKGMGR_REQ_INVALID);
752         return pi->session_id;
753 }
754
755 API const char *pkgmgr_installer_get_license_path(pkgmgr_installer *pi)
756 {
757         CHK_PI_RET(PKGMGR_REQ_INVALID);
758         return pi->license_path;
759 }
760
761 API const char *pkgmgr_installer_get_optional_data(pkgmgr_installer *pi)
762 {
763         CHK_PI_RET(PKGMGR_REQ_INVALID);
764         return pi->optional_data;
765 }
766
767 API int pkgmgr_installer_is_quiet(pkgmgr_installer *pi)
768 {
769         return 1;
770 }
771
772 API int pkgmgr_installer_get_move_type(pkgmgr_installer *pi)
773 {
774         CHK_PI_RET(PKGMGR_REQ_INVALID);
775         return pi->move_type;
776 }
777
778 API const char *pkgmgr_installer_get_caller_pkgid(pkgmgr_installer *pi)
779 {
780         CHK_PI_RET(PKGMGR_REQ_INVALID);
781         return pi->caller_pkgid;
782 }
783
784 API int pkgmgr_installer_get_is_preload(pkgmgr_installer *pi)
785 {
786         CHK_PI_RET(PKGMGR_REQ_INVALID);
787         return pi->is_preload;
788 }
789
790 API int pkgmgr_installer_get_force_removal(pkgmgr_installer *pi)
791 {
792         CHK_PI_RET(PKGMGR_REQ_INVALID);
793         return pi->force_removal;
794 }
795
796 API int pkgmgr_installer_get_is_preload_rw(pkgmgr_installer *pi)
797 {
798         CHK_PI_RET(PKGMGR_REQ_INVALID);
799         return pi->is_preload_rw;
800 }
801
802 API int pkgmgr_installer_get_no_removal(pkgmgr_installer *pi)
803 {
804         CHK_PI_RET(PKGMGR_REQ_INVALID);
805         return pi->no_removal;
806 }
807
808 API int pkgmgr_installer_get_keep_rwdata(pkgmgr_installer *pi)
809 {
810         CHK_PI_RET(PKGMGR_REQ_INVALID);
811         return pi->keep_rwdata;
812 }
813
814 API int pkgmgr_installer_get_partial_rw(pkgmgr_installer *pi)
815 {
816         CHK_PI_RET(PKGMGR_REQ_INVALID);
817         return pi->partial_rw;
818 }
819
820 API int pkgmgr_installer_get_debug_mode(pkgmgr_installer *pi)
821 {
822         CHK_PI_RET(PKGMGR_REQ_INVALID);
823         return pi->debug_mode;
824 }
825
826 API int pkgmgr_installer_get_skip_check_reference(pkgmgr_installer *pi)
827 {
828         CHK_PI_RET(PKGMGR_REQ_INVALID);
829         return pi->skip_check_reference;
830 }
831
832 API int pkgmgr_installer_get_skip_optimization(pkgmgr_installer *pi)
833 {
834         CHK_PI_RET(PKGMGR_REQ_INVALID);
835         return pi->skip_optimization;
836 }
837
838 API int pkgmgr_installer_send_app_uninstall_signal(pkgmgr_installer *pi,
839                              const char *pkg_type,
840                              const char *pkgid,
841                              const char *val)
842 {
843         int ret = 0;
844         ret = __send_signal_for_event(pi, pkg_type, pkgid, NULL,
845                         PKGMGR_INSTALLER_APPID_KEY_STR, val);
846         return ret;
847 }
848
849 API int pkgmgr_installer_send_app_uninstall_signal_for_uid(
850                 pkgmgr_installer *pi, uid_t uid, const char *pkg_type,
851                 const char *pkgid, const char *val)
852 {
853         int ret = 0;
854         ret = __send_signal_for_event_for_uid(pi, uid, pkg_type, pkgid, NULL,
855                         PKGMGR_INSTALLER_APPID_KEY_STR, val);
856         return ret;
857 }
858
859 API int pkgmgr_installer_set_uid(pkgmgr_installer *pi, uid_t uid)
860 {
861         if (pi == NULL)
862                 return -1;
863
864         pi->target_uid = uid;
865         g_target_uid = pi->target_uid;
866
867         return 0;
868 }
869
870 API int
871 pkgmgr_installer_send_app_signal(pkgmgr_installer *pi,
872                              const char *pkg_type,
873                              const char *pkgid,
874                              const char *appid,
875                              const char *key, const char *val)
876 {
877         int r = 0;
878
879         if (!pi->conn) {
880                 ERR("connection is NULL");
881                 return -1;
882         }
883
884         r = __send_signal_for_event(pi, pkg_type, pkgid, appid, key, val);
885
886         return r;
887 }
888
889 API int
890 pkgmgr_installer_send_signal(pkgmgr_installer *pi,
891                              const char *pkg_type,
892                              const char *pkgid,
893                              const char *key, const char *val)
894 {
895         int r = 0;
896
897         if (!pi->conn) {
898                 ERR("connection is NULL");
899                 return -1;
900         }
901
902         if (strcmp(key, PKGMGR_INSTALLER_START_KEY_STR) == 0 &&
903                         strcmp(val, PKGMGR_INSTALLER_UPGRADE_EVENT_STR) == 0)
904                 pi->request_type = PKGMGR_REQ_UPGRADE;
905
906         r = __send_signal_for_event(pi, pkg_type, pkgid, NULL, key, val);
907
908         return r;
909 }
910
911 API int pkgmgr_installer_send_app_signal_for_uid(pkgmgr_installer *pi,
912                 uid_t uid, const char *pkg_type, const char *pkgid,
913                 const char *appid, const char *key, const char *val)
914 {
915         int r = 0;
916
917         if (!pi->conn) {
918                 ERR("connection is NULL");
919                 return -1;
920         }
921
922         r = __send_signal_for_event_for_uid(pi, uid, pkg_type, pkgid, appid,
923                         key, val);
924
925         return r;
926 }
927
928 API int pkgmgr_installer_send_signal_for_uid(pkgmgr_installer *pi,
929                 uid_t uid, const char *pkg_type, const char *pkgid,
930                 const char *key, const char *val)
931 {
932         int r = 0;
933
934         if (!pi->conn) {
935                 ERR("connection is NULL");
936                 return -1;
937         }
938
939         if (strcmp(key, PKGMGR_INSTALLER_START_KEY_STR) == 0 &&
940                         strcmp(val, PKGMGR_INSTALLER_UPGRADE_EVENT_STR) == 0)
941                 pi->request_type = PKGMGR_REQ_UPGRADE;
942
943         r = __send_signal_for_event_for_uid(pi, uid, pkg_type, pkgid, NULL,
944                         key, val);
945
946         return r;
947 }
948
949 API int pkgmgr_installer_set_request_type(pkgmgr_installer *pi, int request_type)
950 {
951         if (pi == NULL)
952                 return -1;
953
954         pi->request_type = request_type;
955         return 0;
956 }
957
958 API int pkgmgr_installer_set_session_id(pkgmgr_installer *pi, const char *session_id)
959 {
960         if (pi == NULL || session_id == NULL)
961                 return -1;
962
963         pi->session_id = strndup(session_id, MAX_STRLEN);
964         return 0;
965 }
966
967 API int pkgmgr_installer_create_certinfo_set_handle(pkgmgr_instcertinfo_h *handle)
968 {
969         int ret = 0;
970         ret = pkgmgrinfo_create_certinfo_set_handle(handle);
971         return ret;
972 }
973
974 API int pkgmgr_installer_set_cert_value(pkgmgr_instcertinfo_h handle, pkgmgr_instcert_type cert_type, char *cert_value)
975 {
976         int ret = 0;
977         ret = pkgmgrinfo_set_cert_value(handle, cert_type, cert_value);
978         return ret;
979 }
980
981 API int pkgmgr_installer_save_certinfo(const char *pkgid, pkgmgr_instcertinfo_h handle, uid_t uid)
982 {
983         int ret = 0;
984         ret = pkgmgrinfo_save_certinfo(pkgid, handle, uid);
985         return ret;
986 }
987
988 API int pkgmgr_installer_destroy_certinfo_set_handle(pkgmgr_instcertinfo_h handle)
989 {
990         int ret = 0;
991         ret = pkgmgrinfo_destroy_certinfo_set_handle(handle);
992         return ret;
993 }
994
995 API int pkgmgr_installer_delete_certinfo(const char *pkgid)
996 {
997         int ret = 0;
998         ret = pkgmgrinfo_delete_certinfo(pkgid);
999         return ret;
1000 }
1001
1002 API int pkgmgr_installer_set_privilege_level(pkgmgr_privilege_level level)
1003 {
1004         g_privilege_level = level;
1005
1006         return 0;
1007 }
1008
1009 API int pkgmgr_installer_info_get_target_uid(uid_t *uid)
1010 {
1011         *uid = g_target_uid;
1012
1013         return 0;
1014 }
1015
1016 API int pkgmgr_installer_info_get_privilege_level(pkgmgr_privilege_level *level)
1017 {
1018         *level = g_privilege_level;
1019
1020         return 0;
1021 }
1022
1023 API int pkgmgr_installer_info_get_debug_mode(int *debug_mode)
1024 {
1025         *debug_mode = g_debug_mode;
1026         return 0;
1027 }
1028
1029 API int pkgmgr_installer_info_get_skip_optimization(int *skip_optimization)
1030 {
1031         *skip_optimization = g_skip_optimization;
1032         return 0;
1033 }
1034
1035 #define CASE_TO_STR(ERRCODE) case ERRCODE: return ERRCODE##_STR
1036 API const char *pkgmgr_installer_error_to_string(int error_code)
1037 {
1038         switch (error_code) {
1039         CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_UNDEFINED_ERROR);
1040         CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_GLOBALSYMLINK_ERROR);
1041         CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_GRANT_PERMISSION_ERROR);
1042         CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_IMAGE_ERROR);
1043         CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_UNZIP_ERROR);
1044         CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_SECURITY_ERROR);
1045         CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_REGISTER_ERROR);
1046         CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_PRIVILEGE_ERROR);
1047         CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_PARSE_ERROR);
1048         CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_RECOVERY_ERROR);
1049         CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_DELTA_ERROR);
1050         CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_APP_DIR_ERROR);
1051         CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_CONFIG_ERROR);
1052         CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_SIGNATURE_ERROR);
1053         CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_SIGNATURE_INVALID);
1054         CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_CERT_ERROR);
1055         CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_AUTHOR_CERT_NOT_MATCH);
1056         CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_AUTHOR_CERT_NOT_FOUND);
1057         CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_ICON_ERROR);
1058         CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_ICON_NOT_FOUND);
1059         CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_MANIFEST_ERROR);
1060         CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_MANIFEST_NOT_FOUND);
1061         CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_PACKAGE_NOT_FOUND);
1062         CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_OPERATION_NOT_ALLOWED);
1063         CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_OUT_OF_SPACE);
1064         CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_INVALID_VALUE);
1065         CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_ERROR);
1066         CASE_TO_STR(PKGMGR_INSTALLER_ERRCODE_OK);
1067         default:
1068                 return PKGMGR_INSTALLER_ERRCODE_UNDEFINED_ERROR_STR;
1069         }
1070 }
1071
1072 API int pkgmgr_installer_add_pkg(pkgmgr_installer *pi,
1073                 const char *pkgid, const char *pkg_type)
1074 {
1075         pkg_signal_info *info;
1076         if (!pi || !pkgid || !pkg_type) {
1077                 ERR("invalid argument");
1078                 return -1;
1079         }
1080
1081         info = calloc(1, sizeof(pkg_signal_info));
1082         if (!info) {
1083                 ERR("out of memory");
1084                 return -1;
1085         }
1086
1087         info->pkgid = strdup(pkgid);
1088         info->pkg_type = strdup(pkg_type);
1089         if (!info->pkgid || !info->pkg_type) {
1090                 ERR("out of memory");
1091                 free(info->pkgid);
1092                 free(info->pkg_type);
1093                 free(info);
1094                 return -1;
1095         }
1096         g_hash_table_insert(pi->pkg_list, (gpointer)info->pkgid, (gpointer)info);
1097
1098         return 0;
1099 }
1100
1101 static void __build_multi_signal(gpointer key, gpointer value,
1102                 gpointer user_data)
1103 {
1104         GVariantBuilder *builder = (GVariantBuilder *)user_data;
1105         pkg_signal_info *info = (pkg_signal_info *)value;
1106
1107         g_variant_builder_add(builder, "(sss)", info->pkgid, "", info->pkg_type);
1108 }
1109
1110 API int pkgmgr_installer_send_signals(pkgmgr_installer *pi,
1111                 const char *key, const char *val)
1112 {
1113         char *sid;
1114         const char *signal_name;
1115         GError *err = NULL;
1116         GVariantBuilder *builder;
1117
1118         if (!pi || !key || !val) {
1119                 ERR("invalid argument");
1120                 return -1;
1121         }
1122
1123         sid = pi->session_id;
1124         if (!sid)
1125                 sid = "";
1126
1127         signal_name = __get_signal_name(pi, key, "");
1128         if (!signal_name) {
1129                 ERR("unknown signal type");
1130                 return -1;
1131         }
1132
1133         builder = g_variant_builder_new(G_VARIANT_TYPE("a(sss)"));
1134         g_hash_table_foreach(pi->pkg_list, __build_multi_signal, builder);
1135         if (g_dbus_connection_emit_signal(pi->conn, NULL,
1136                                 PKGMGR_INSTALLER_DBUS_OBJECT_PATH,
1137                                 PKGMGR_INSTALLER_DBUS_INTERFACE, signal_name,
1138                                 g_variant_new("(usa(sss)ss)",
1139                                                 pi->target_uid, sid, builder, key,
1140                                                 val), &err) != TRUE) {
1141                 ERR("failed to send dbus signal");
1142                 if (err) {
1143                         ERR("err: %s", err->message);
1144                         g_error_free(err);
1145                 }
1146                 g_variant_builder_unref(builder);
1147                 return -1;
1148         }
1149         g_variant_builder_unref(builder);
1150
1151         return 0;
1152 }
1153
1154 API int pkgmgr_installer_send_signals_for_uid(pkgmgr_installer *pi, uid_t uid,
1155                 const char *key, const char *val)
1156 {
1157         char *sid;
1158         size_t data_len;
1159         size_t name_size;
1160         GVariant *gv;
1161         GVariantBuilder *builder;
1162         gsize gv_len;
1163         gpointer gv_data;
1164         void *data;
1165         void *ptr;
1166         const char *signal_name;
1167
1168         if (!pi || !pi->conn) {
1169                 ERR("connection is NULL");
1170                 return -1;
1171         }
1172
1173         sid = pi->session_id;
1174         if (!sid)
1175                 sid = "";
1176
1177         data_len = sizeof(size_t) + sizeof(gsize);
1178
1179         /* including null byte */
1180         signal_name = __get_signal_name(pi, key, "");
1181         if (!signal_name) {
1182                 ERR("unknown signal type");
1183                 return -1;
1184         }
1185         name_size = strlen(signal_name) + 1;
1186         data_len += name_size;
1187
1188         builder = g_variant_builder_new(G_VARIANT_TYPE("a(sss)"));
1189         g_hash_table_foreach(pi->pkg_list, __build_multi_signal, builder);
1190
1191         gv = g_variant_new("(usa(sss)ss)", uid, sid, builder, key, val);
1192         g_variant_builder_unref(builder);
1193         if (gv == NULL) {
1194                 ERR("failed to create GVariant instance");
1195                 return -1;
1196         }
1197
1198         gv_len = g_variant_get_size(gv);
1199         gv_data = g_malloc(gv_len);
1200         g_variant_store(gv, gv_data);
1201         g_variant_unref(gv);
1202         data_len += gv_len;
1203
1204         data = malloc(data_len);
1205         if (data == NULL) {
1206                 ERR("out of memory");
1207                 g_free(gv_data);
1208                 return -1;
1209         }
1210         ptr = data;
1211         memcpy(ptr, &name_size, sizeof(size_t));
1212         ptr += sizeof(size_t);
1213         memcpy(ptr, &gv_len, sizeof(gsize));
1214         ptr += sizeof(gsize);
1215         memcpy(ptr, signal_name, name_size);
1216         ptr += name_size;
1217         memcpy(ptr, gv_data, gv_len);
1218         g_free(gv_data);
1219
1220         if (__send_signal_to_agent(uid, data, data_len)) {
1221                 ERR("failed to send signal to agent");
1222                 free(data);
1223                 return -1;
1224         }
1225
1226         free(data);
1227
1228         return 0;
1229 }