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