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