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