4 * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.
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>
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
13 * http://www.apache.org/licenses/LICENSE-2.0
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.
29 #include <sys/types.h>
30 #include <sys/socket.h>
36 #include "pkgmgr_installer.h"
37 #include "pkgmgr_installer_config.h"
38 #include "pkgmgr_installer_debug.h"
39 #include "pkgmgr_installer_info.h"
41 #include "../client/include/comm_config.h"
43 #include <pkgmgr-info.h>
45 /* API export macro */
47 #define API __attribute__ ((visibility("default")))
50 #define MAX_STRLEN 1024
51 #define MAX_QUERY_LEN 4096
53 #define CHK_PI_RET(r) \
54 do { if (NULL == pi) return (r); } while (0)
56 struct pkgmgr_installer {
70 GDBusConnection *conn;
73 static uid_t g_target_uid;
75 static const char *__get_signal_name(pkgmgr_installer *pi, const char *key)
77 if (strcmp(key, PKGMGR_INSTALLER_INSTALL_PERCENT_KEY_STR) == 0)
78 return COMM_STATUS_BROADCAST_EVENT_INSTALL_PROGRESS;
79 else if (strcmp(key, PKGMGR_INSTALLER_GET_SIZE_KEY_STR) == 0)
80 return COMM_STATUS_BROADCAST_EVENT_GET_SIZE;
81 else if (strcmp(key, PKGMGR_INSTALLER_APPID_KEY_STR) == 0)
82 return COMM_STATUS_BROADCAST_EVENT_UNINSTALL;
84 switch (pi->request_type) {
85 case PKGMGR_REQ_INSTALL:
86 case PKGMGR_REQ_MANIFEST_DIRECT_INSTALL:
87 case PKGMGR_REQ_MOUNT_INSTALL:
88 return COMM_STATUS_BROADCAST_EVENT_INSTALL;
89 case PKGMGR_REQ_UNINSTALL:
90 return COMM_STATUS_BROADCAST_EVENT_UNINSTALL;
91 case PKGMGR_REQ_UPGRADE:
92 return COMM_STATUS_BROADCAST_EVENT_UPGRADE;
94 return COMM_STATUS_BROADCAST_EVENT_MOVE;
95 case PKGMGR_REQ_ENABLE_APP:
96 return COMM_STATUS_BROADCAST_EVENT_ENABLE_APP;
97 case PKGMGR_REQ_DISABLE_APP:
98 return COMM_STATUS_BROADCAST_EVENT_DISABLE_APP;
99 case PKGMGR_REQ_ENABLE_APP_SPLASH_SCREEN:
100 return COMM_STATUS_BROADCAST_EVENT_ENABLE_APP_SPLASH_SCREEN;
101 case PKGMGR_REQ_DISABLE_APP_SPLASH_SCREEN:
102 return COMM_STATUS_BROADCAST_EVENT_DISABLE_APP_SPLASH_SCREEN;
105 ERR("cannot find type, send signal with type SIGNAL_STATUS");
107 return COMM_STATUS_BROADCAST_SIGNAL_STATUS;
110 static int __send_signal_for_app_event(pkgmgr_installer *pi, const char *pkg_type,
111 const char *pkgid, const char *appid, const char *key, const char *val)
117 if (!pi || pi->conn == NULL || appid == NULL)
120 sid = pi->session_id;
124 name = __get_signal_name(pi, key);
126 ERR("unknown signal type");
130 if (g_dbus_connection_emit_signal(pi->conn, NULL,
131 COMM_STATUS_BROADCAST_OBJECT_PATH,
132 COMM_STATUS_BROADCAST_INTERFACE, name,
133 g_variant_new("(ussssss)", pi->target_uid, sid,
134 pkg_type, pkgid, appid, key, val), &err)
136 ERR("failed to send dbus signal: %s", err->message);
144 static int __send_signal_for_event(pkgmgr_installer *pi, const char *pkg_type,
145 const char *pkgid, const char *key, const char *val)
151 if (!pi || pi->conn == NULL)
154 sid = pi->session_id;
158 name = __get_signal_name(pi, key);
160 ERR("unknown signal type");
164 if (g_dbus_connection_emit_signal(pi->conn, NULL,
165 COMM_STATUS_BROADCAST_OBJECT_PATH,
166 COMM_STATUS_BROADCAST_INTERFACE, name,
167 g_variant_new("(ussssss)", pi->target_uid, sid,
168 pkg_type, pkgid, "", key, val), &err)
170 ERR("failed to send dbus signal: %s", err->message);
178 static int __send_signal_to_agent(uid_t uid, void *data, size_t len)
181 struct sockaddr_un sa;
184 fd = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0);
186 ERR("failed to create socket: %d", errno);
190 sa.sun_family = AF_UNIX;
191 snprintf(sa.sun_path, sizeof(sa.sun_path), "/run/pkgmgr/agent/%d", uid);
193 r = connect(fd, (struct sockaddr *)&sa, sizeof(sa));
195 ERR("failed to connect socket(%s): %d", sa.sun_path, errno);
200 r = send(fd, data, len, 0);
202 ERR("failed to send data: %d", errno);
212 /* TODO: it should be refactored */
213 static int __send_app_signal_for_event_for_uid(pkgmgr_installer *pi, uid_t uid,
214 const char *pkg_type, const char *pkgid, const char *appid,
215 const char *key, const char *val)
227 if (!pi || pi->conn == NULL)
230 sid = pi->session_id;
234 data_len = sizeof(size_t) + sizeof(gsize);
236 name = __get_signal_name(pi, key);
238 ERR("unknown signal type");
241 /* including null byte */
242 name_size = strlen(name) + 1;
243 data_len += name_size;
245 gv = g_variant_new("(ussssss)", pi->target_uid, sid,
246 pkg_type, pkgid, appid, key, val);
247 gv_len = g_variant_get_size(gv);
248 gv_data = g_malloc(gv_len);
249 g_variant_store(gv, gv_data);
253 data = malloc(data_len);
255 memcpy(ptr, &name_size, sizeof(size_t));
256 ptr += sizeof(size_t);
257 memcpy(ptr, &gv_len, sizeof(gsize));
258 ptr += sizeof(gsize);
259 memcpy(ptr, name, name_size);
261 memcpy(ptr, gv_data, gv_len);
263 if (__send_signal_to_agent(uid, data, data_len)) {
264 ERR("failed to send signal to agent");
275 /* TODO: it should be refactored */
276 static int __send_signal_for_event_for_uid(pkgmgr_installer *pi, uid_t uid,
277 const char *pkg_type, const char *pkgid,
278 const char *key, const char *val)
290 if (!pi || pi->conn == NULL)
293 sid = pi->session_id;
297 data_len = sizeof(size_t) + sizeof(gsize);
299 name = __get_signal_name(pi, key);
301 ERR("unknown signal type");
304 /* including null byte */
305 name_size = strlen(name) + 1;
306 data_len += name_size;
308 gv = g_variant_new("(ussssss)", pi->target_uid, sid,
309 pkg_type, pkgid, "", key, val);
310 gv_len = g_variant_get_size(gv);
311 gv_data = g_malloc(gv_len);
312 g_variant_store(gv, gv_data);
316 data = malloc(data_len);
318 memcpy(ptr, &name_size, sizeof(size_t));
319 ptr += sizeof(size_t);
320 memcpy(ptr, &gv_len, sizeof(gsize));
321 ptr += sizeof(gsize);
322 memcpy(ptr, name, name_size);
324 memcpy(ptr, gv_data, gv_len);
326 if (__send_signal_to_agent(uid, data, data_len)) {
327 ERR("failed to send signal to agent");
338 API pkgmgr_installer *pkgmgr_installer_new(void)
340 pkgmgr_installer *pi;
343 pi = calloc(1, sizeof(struct pkgmgr_installer));
347 pi->conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
348 if (pi->conn == NULL) {
349 ERR("failed to get bus: %s", err->message);
357 pi->request_type = PKGMGR_REQ_INVALID;
362 API pkgmgr_installer *pkgmgr_installer_offline_new(void)
364 pkgmgr_installer *pi;
366 pi = calloc(1, sizeof(struct pkgmgr_installer));
372 pi->request_type = PKGMGR_REQ_INVALID;
377 API int pkgmgr_installer_free(pkgmgr_installer *pi)
383 free(pi->pkgmgr_info);
385 free(pi->session_id);
386 if (pi->optional_data)
387 free(pi->optional_data);
388 if (pi->caller_pkgid)
389 free(pi->caller_pkgid);
394 g_dbus_connection_flush_sync(pi->conn, NULL, NULL);
395 g_object_unref(pi->conn);
404 pkgmgr_installer_receive_request(pkgmgr_installer *pi,
405 const int argc, char **argv)
412 optind = 1; /* Initialize optind to clear prev. index */
417 pi->target_uid = getuid();
418 g_target_uid = pi->target_uid;
420 c = getopt_long(argc, argv, short_opts, long_opts, &opt_idx);
421 /* printf("c=%d %c\n", c, c); //debug */
423 break; /* Parse is end */
425 case OPTVAL_PRELOAD: /* request for preload app */
427 DBG("preload request [%d]", pi->is_preload);
429 case OPTVAL_FORCE_REMOVAL: /* request for force-remove */
430 pi->force_removal = 1;
431 DBG("force-remove request [%d]", pi->force_removal);
433 case 'k': /* session id */
435 free(pi->session_id);
436 pi->session_id = strndup(optarg, MAX_STRLEN);
439 case 'l': /* license path */
440 if (pi->license_path)
441 free(pi->license_path);
442 pi->license_path = strndup(optarg, MAX_STRLEN);
445 case 'i': /* install */
451 pi->request_type = PKGMGR_REQ_INSTALL;
453 free(pi->pkgmgr_info);
454 pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
455 DBG("option is [i] pkgid[%s]", pi->pkgmgr_info);
456 if (pi->pkgmgr_info && strlen(pi->pkgmgr_info) == 0)
457 free(pi->pkgmgr_info);
462 case 'e': /* install */
465 pi->tep_path = strndup(optarg, MAX_STRLEN);
466 pi->is_tep_included = 1;
467 DBG("option is [e] tep_path[%s]", pi->tep_path);
470 case 'M': /* install */
471 if (strcmp(optarg, "tep_move") == 0)
475 DBG("option is [M] tep_move[%d]", pi->tep_move);
478 case 'd': /* uninstall */
484 pi->request_type = PKGMGR_REQ_UNINSTALL;
486 free(pi->pkgmgr_info);
487 pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
491 case 'c': /* clear */
497 pi->request_type = PKGMGR_REQ_CLEAR;
499 free(pi->pkgmgr_info);
500 pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
509 pi->request_type = PKGMGR_REQ_MOVE;
511 free(pi->pkgmgr_info);
512 pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
515 case 'r': /* reinstall */
521 pi->request_type = PKGMGR_REQ_REINSTALL;
523 free(pi->pkgmgr_info);
524 pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
527 case 't': /* move type*/
528 pi->move_type = atoi(optarg);
531 case 'p': /* caller pkgid*/
532 if (pi->caller_pkgid)
533 free(pi->caller_pkgid);
534 pi->caller_pkgid = strndup(optarg, MAX_STRLEN);
538 case 's': /* smack */
544 pi->request_type = PKGMGR_REQ_SMACK;
546 free(pi->pkgmgr_info);
547 pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
550 case 'o': /* optional data*/
551 pi->optional_data = strndup(optarg, MAX_STRLEN);
554 case 'y': /* pkgid for direct manifest installation */
556 pi->request_type = PKGMGR_REQ_MANIFEST_DIRECT_INSTALL;
557 pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
560 case 'w': /* pkgid for mount installation */
562 pi->request_type = PKGMGR_REQ_MOUNT_INSTALL;
563 pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
566 case 'b': /* recovery */
572 pi->request_type = PKGMGR_REQ_RECOVER;
574 free(pi->pkgmgr_info);
575 pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
578 case 'D': /* disable pkg */
579 pi->request_type = PKGMGR_REQ_DISABLE_PKG;
581 free(pi->pkgmgr_info);
582 pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
585 case 'A': /* enable pkg */
586 pi->request_type = PKGMGR_REQ_ENABLE_PKG;
588 free(pi->pkgmgr_info);
589 pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
593 g_target_uid = (uid_t)atoi(optarg);
594 pi->target_uid = (uid_t)atoi(optarg);
598 case '?': /* Not an option */
611 API int pkgmgr_installer_get_request_type(pkgmgr_installer *pi)
613 CHK_PI_RET(PKGMGR_REQ_INVALID);
614 return pi->request_type;
617 API uid_t pkgmgr_installer_get_uid(pkgmgr_installer *pi)
619 CHK_PI_RET(PKGMGR_REQ_INVALID);
620 return pi->target_uid;
623 API const char *pkgmgr_installer_get_request_info(pkgmgr_installer *pi)
625 CHK_PI_RET(PKGMGR_REQ_INVALID);
626 return pi->pkgmgr_info;
629 API const char *pkgmgr_installer_get_tep_path(pkgmgr_installer *pi)
631 CHK_PI_RET(PKGMGR_REQ_INVALID);
635 API int pkgmgr_installer_get_tep_move_type(pkgmgr_installer *pi)
637 CHK_PI_RET(PKGMGR_REQ_INVALID);
641 API const char *pkgmgr_installer_get_session_id(pkgmgr_installer *pi)
643 CHK_PI_RET(PKGMGR_REQ_INVALID);
644 return pi->session_id;
647 API const char *pkgmgr_installer_get_license_path(pkgmgr_installer *pi)
649 CHK_PI_RET(PKGMGR_REQ_INVALID);
650 return pi->license_path;
653 API const char *pkgmgr_installer_get_optional_data(pkgmgr_installer *pi)
655 CHK_PI_RET(PKGMGR_REQ_INVALID);
656 return pi->optional_data;
659 API int pkgmgr_installer_is_quiet(pkgmgr_installer *pi)
664 API int pkgmgr_installer_get_move_type(pkgmgr_installer *pi)
666 CHK_PI_RET(PKGMGR_REQ_INVALID);
667 return pi->move_type;
670 API const char *pkgmgr_installer_get_caller_pkgid(pkgmgr_installer *pi)
672 CHK_PI_RET(PKGMGR_REQ_INVALID);
673 return pi->caller_pkgid;
676 API int pkgmgr_installer_get_is_preload(pkgmgr_installer *pi)
678 CHK_PI_RET(PKGMGR_REQ_INVALID);
679 return pi->is_preload;
682 API int pkgmgr_installer_get_force_removal(pkgmgr_installer *pi)
684 CHK_PI_RET(PKGMGR_REQ_INVALID);
685 return pi->force_removal;
688 API int pkgmgr_installer_send_app_uninstall_signal(pkgmgr_installer *pi,
689 const char *pkg_type,
694 ret = __send_signal_for_event(pi, pkg_type, pkgid,
695 PKGMGR_INSTALLER_APPID_KEY_STR, val);
699 API int pkgmgr_installer_set_uid(pkgmgr_installer *pi, uid_t uid)
704 pi->target_uid = uid;
705 g_target_uid = pi->target_uid;
711 pkgmgr_installer_send_app_signal(pkgmgr_installer *pi,
712 const char *pkg_type,
715 const char *key, const char *val)
720 ERR("connection is NULL");
724 r = __send_signal_for_app_event(pi, pkg_type, pkgid, appid, key, val);
730 pkgmgr_installer_send_signal(pkgmgr_installer *pi,
731 const char *pkg_type,
733 const char *key, const char *val)
738 ERR("connection is NULL");
742 if (strcmp(key, PKGMGR_INSTALLER_START_KEY_STR) == 0 &&
743 strcmp(val, PKGMGR_INSTALLER_UPGRADE_EVENT_STR) == 0)
744 pi->request_type = PKGMGR_REQ_UPGRADE;
746 r = __send_signal_for_event(pi, pkg_type, pkgid, key, val);
751 API int pkgmgr_installer_send_app_signal_for_uid(pkgmgr_installer *pi,
752 uid_t uid, const char *pkg_type, const char *pkgid,
753 const char *appid, const char *key, const char *val)
758 ERR("connection is NULL");
762 r = __send_app_signal_for_event_for_uid(pi, uid, pkg_type, pkgid, appid, key, val);
767 API int pkgmgr_installer_send_signal_for_uid(pkgmgr_installer *pi,
768 uid_t uid, const char *pkg_type, const char *pkgid,
769 const char *key, const char *val)
774 ERR("connection is NULL");
778 if (strcmp(key, PKGMGR_INSTALLER_START_KEY_STR) == 0 &&
779 strcmp(val, PKGMGR_INSTALLER_UPGRADE_EVENT_STR) == 0)
780 pi->request_type = PKGMGR_REQ_UPGRADE;
782 r = __send_signal_for_event_for_uid(pi, uid, pkg_type, pkgid, key, val);
787 API int pkgmgr_installer_set_request_type(pkgmgr_installer *pi, int request_type)
792 pi->request_type = request_type;
796 API int pkgmgr_installer_set_session_id(pkgmgr_installer *pi, const char *session_id)
798 if (pi == NULL || session_id == NULL)
801 pi->session_id = strndup(session_id, MAX_STRLEN);
805 API int pkgmgr_installer_create_certinfo_set_handle(pkgmgr_instcertinfo_h *handle)
808 ret = pkgmgrinfo_create_certinfo_set_handle(handle);
812 API int pkgmgr_installer_set_cert_value(pkgmgr_instcertinfo_h handle, pkgmgr_instcert_type cert_type, char *cert_value)
815 ret = pkgmgrinfo_set_cert_value(handle, cert_type, cert_value);
819 API int pkgmgr_installer_save_certinfo(const char *pkgid, pkgmgr_instcertinfo_h handle, uid_t uid)
822 ret = pkgmgrinfo_save_certinfo(pkgid, handle, uid);
826 API int pkgmgr_installer_destroy_certinfo_set_handle(pkgmgr_instcertinfo_h handle)
829 ret = pkgmgrinfo_destroy_certinfo_set_handle(handle);
833 API int pkgmgr_installer_delete_certinfo(const char *pkgid)
836 ret = pkgmgrinfo_delete_certinfo(pkgid);
840 API int pkgmgr_installer_info_get_target_uid(uid_t *uid)