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>
35 #include <tzplatform_config.h>
37 #include "pkgmgr_installer.h"
38 #include "pkgmgr_installer_config.h"
39 #include "pkgmgr_installer_debug.h"
40 #include "pkgmgr_installer_info.h"
42 #include <pkgmgr-info.h>
44 /* API export macro */
46 #define API __attribute__ ((visibility("default")))
49 #define MAX_STRLEN 1024
50 #define MAX_QUERY_LEN 4096
52 #define CHK_PI_RET(r) \
53 do { if (NULL == pi) return (r); } while (0)
55 #define OPTVAL_PRELOAD 1000
56 #define OPTVAL_FORCE_REMOVAL 1001
58 /* Supported options */
59 const char *short_opts = "k:l:i:d:c:m:t:o:r:p:s:b:e:M:y:u:w:D:A:q";
60 const struct option long_opts[] = {
61 { "session-id", 1, NULL, 'k' },
62 { "license-path", 1, NULL, 'l' },
63 { "install", 1, NULL, 'i' },
64 { "uninstall", 1, NULL, 'd' },
65 { "clear", 1, NULL, 'c' },
66 { "move", 1, NULL, 'm' },
67 { "move-type", 1, NULL, 't' },
68 { "optional-data", 0, NULL, 'o' },
69 { "reinstall", 0, NULL, 'r' },
70 { "caller-pkgid", 1, NULL, 'p' },
71 { "tep-path", 1, NULL, 'e' },
72 { "tep-move", 1, NULL, 'M' },
73 { "smack", 1, NULL, 's' },
74 { "direct-manifest-install", 1, NULL, 'y' },
75 { "mount-install", 1, NULL, 'w' },
76 { "recovery", 1, NULL, 'b' },
77 { "preload", 0, NULL, OPTVAL_PRELOAD },
78 { "force-remove", 0, NULL, OPTVAL_FORCE_REMOVAL },
79 { 0, 0, 0, 0 } /* sentinel */
82 struct pkgmgr_installer {
96 GDBusConnection *conn;
99 static uid_t g_target_uid;
101 static const char *__get_signal_name(pkgmgr_installer *pi, const char *key)
103 if (strcmp(key, PKGMGR_INSTALLER_INSTALL_PERCENT_KEY_STR) == 0)
105 else if (strcmp(key, PKGMGR_INSTALLER_GET_SIZE_KEY_STR) == 0)
107 else if (strcmp(key, PKGMGR_INSTALLER_APPID_KEY_STR) == 0)
108 return PKGMGR_INSTALLER_UNINSTALL_EVENT_STR;
110 switch (pi->request_type) {
111 case PKGMGR_REQ_INSTALL:
112 case PKGMGR_REQ_MANIFEST_DIRECT_INSTALL:
113 case PKGMGR_REQ_MOUNT_INSTALL:
114 case PKGMGR_REQ_ENABLE_PKG:
115 return PKGMGR_INSTALLER_INSTALL_EVENT_STR;
116 case PKGMGR_REQ_UNINSTALL:
117 case PKGMGR_REQ_DISABLE_PKG:
118 return PKGMGR_INSTALLER_UNINSTALL_EVENT_STR;
119 case PKGMGR_REQ_UPGRADE:
120 return PKGMGR_INSTALLER_UPGRADE_EVENT_STR;
121 case PKGMGR_REQ_MOVE:
122 return PKGMGR_INSTALLER_MOVE_EVENT_STR;
123 case PKGMGR_REQ_ENABLE_APP:
124 return PKGMGR_INSTALLER_APP_ENABLE_EVENT_STR;
125 case PKGMGR_REQ_DISABLE_APP:
126 return PKGMGR_INSTALLER_APP_DISABLE_EVENT_STR;
127 case PKGMGR_REQ_ENABLE_APP_SPLASH_SCREEN:
128 return PKGMGR_INSTALLER_APP_ENABLE_SPLASH_SCREEN_EVENT_STR;
129 case PKGMGR_REQ_DISABLE_APP_SPLASH_SCREEN:
130 return PKGMGR_INSTALLER_APP_DISABLE_SPLASH_SCREEN_EVENT_STR;
133 ERR("cannot find type");
138 static int __send_signal_for_app_event(pkgmgr_installer *pi, const char *pkg_type,
139 const char *pkgid, const char *appid, const char *key, const char *val)
145 if (!pi || pi->conn == NULL || appid == NULL)
148 sid = pi->session_id;
152 name = __get_signal_name(pi, key);
154 ERR("unknown signal type");
158 if (g_dbus_connection_emit_signal(pi->conn, NULL,
159 PKGMGR_INSTALLER_DBUS_OBJECT_PATH,
160 PKGMGR_INSTALLER_DBUS_INTERFACE, name,
161 g_variant_new("(ussssss)", pi->target_uid, sid,
162 pkg_type, pkgid, appid, key, val), &err)
164 ERR("failed to send dbus signal: %s", err->message);
172 static int __send_signal_for_event(pkgmgr_installer *pi, const char *pkg_type,
173 const char *pkgid, const char *key, const char *val)
179 if (!pi || pi->conn == NULL)
182 sid = pi->session_id;
186 name = __get_signal_name(pi, key);
188 ERR("unknown signal type");
192 if (g_dbus_connection_emit_signal(pi->conn, NULL,
193 PKGMGR_INSTALLER_DBUS_OBJECT_PATH,
194 PKGMGR_INSTALLER_DBUS_INTERFACE, name,
195 g_variant_new("(ussssss)", pi->target_uid, sid,
196 pkg_type, pkgid, "", key, val), &err)
198 ERR("failed to send dbus signal: %s", err->message);
206 static int __send_signal_to_agent(uid_t uid, void *data, size_t len)
209 struct sockaddr_un sa;
212 fd = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0);
214 ERR("failed to create socket: %d", errno);
218 sa.sun_family = AF_UNIX;
219 snprintf(sa.sun_path, sizeof(sa.sun_path), "/run/pkgmgr/agent/%d", uid);
221 r = connect(fd, (struct sockaddr *)&sa, sizeof(sa));
223 ERR("failed to connect socket(%s): %d", sa.sun_path, errno);
228 r = send(fd, data, len, 0);
230 ERR("failed to send data: %d", errno);
240 /* TODO: it should be refactored */
241 static int __send_app_signal_for_event_for_uid(pkgmgr_installer *pi, uid_t uid,
242 const char *pkg_type, const char *pkgid, const char *appid,
243 const char *key, const char *val)
255 if (!pi || pi->conn == NULL)
258 sid = pi->session_id;
262 data_len = sizeof(size_t) + sizeof(gsize);
264 name = __get_signal_name(pi, key);
266 ERR("unknown signal type");
269 /* including null byte */
270 name_size = strlen(name) + 1;
271 data_len += name_size;
273 gv = g_variant_new("(ussssss)", pi->target_uid, sid,
274 pkg_type, pkgid, appid, key, val);
275 gv_len = g_variant_get_size(gv);
276 gv_data = g_malloc(gv_len);
277 g_variant_store(gv, gv_data);
281 data = malloc(data_len);
283 memcpy(ptr, &name_size, sizeof(size_t));
284 ptr += sizeof(size_t);
285 memcpy(ptr, &gv_len, sizeof(gsize));
286 ptr += sizeof(gsize);
287 memcpy(ptr, name, name_size);
289 memcpy(ptr, gv_data, gv_len);
291 if (__send_signal_to_agent(uid, data, data_len)) {
292 ERR("failed to send signal to agent");
303 /* TODO: it should be refactored */
304 static int __send_signal_for_event_for_uid(pkgmgr_installer *pi, uid_t uid,
305 const char *pkg_type, const char *pkgid,
306 const char *key, const char *val)
318 if (!pi || pi->conn == NULL)
321 sid = pi->session_id;
325 data_len = sizeof(size_t) + sizeof(gsize);
327 name = __get_signal_name(pi, key);
329 ERR("unknown signal type");
332 /* including null byte */
333 name_size = strlen(name) + 1;
334 data_len += name_size;
336 gv = g_variant_new("(ussssss)", pi->target_uid, sid,
337 pkg_type, pkgid, "", key, val);
338 gv_len = g_variant_get_size(gv);
339 gv_data = g_malloc(gv_len);
340 g_variant_store(gv, gv_data);
344 data = malloc(data_len);
346 memcpy(ptr, &name_size, sizeof(size_t));
347 ptr += sizeof(size_t);
348 memcpy(ptr, &gv_len, sizeof(gsize));
349 ptr += sizeof(gsize);
350 memcpy(ptr, name, name_size);
352 memcpy(ptr, gv_data, gv_len);
354 if (__send_signal_to_agent(uid, data, data_len)) {
355 ERR("failed to send signal to agent");
366 API pkgmgr_installer *pkgmgr_installer_new(void)
368 pkgmgr_installer *pi;
371 pi = calloc(1, sizeof(struct pkgmgr_installer));
375 pi->conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
376 if (pi->conn == NULL) {
377 ERR("failed to get bus: %s", err->message);
385 pi->request_type = PKGMGR_REQ_INVALID;
390 API pkgmgr_installer *pkgmgr_installer_offline_new(void)
392 pkgmgr_installer *pi;
394 pi = calloc(1, sizeof(struct pkgmgr_installer));
400 pi->request_type = PKGMGR_REQ_INVALID;
405 API int pkgmgr_installer_free(pkgmgr_installer *pi)
411 free(pi->pkgmgr_info);
413 free(pi->session_id);
414 if (pi->optional_data)
415 free(pi->optional_data);
416 if (pi->caller_pkgid)
417 free(pi->caller_pkgid);
422 g_dbus_connection_flush_sync(pi->conn, NULL, NULL);
423 g_object_unref(pi->conn);
432 pkgmgr_installer_receive_request(pkgmgr_installer *pi,
433 const int argc, char **argv)
440 optind = 1; /* Initialize optind to clear prev. index */
445 pi->target_uid = getuid();
446 g_target_uid = pi->target_uid;
448 c = getopt_long(argc, argv, short_opts, long_opts, &opt_idx);
449 /* printf("c=%d %c\n", c, c); //debug */
451 break; /* Parse is end */
453 case OPTVAL_PRELOAD: /* request for preload app */
455 DBG("preload request [%d]", pi->is_preload);
457 case OPTVAL_FORCE_REMOVAL: /* request for force-remove */
458 pi->force_removal = 1;
459 DBG("force-remove request [%d]", pi->force_removal);
461 case 'k': /* session id */
463 free(pi->session_id);
464 pi->session_id = strndup(optarg, MAX_STRLEN);
467 case 'l': /* license path */
468 if (pi->license_path)
469 free(pi->license_path);
470 pi->license_path = strndup(optarg, MAX_STRLEN);
473 case 'i': /* install */
479 pi->request_type = PKGMGR_REQ_INSTALL;
481 free(pi->pkgmgr_info);
482 pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
483 DBG("option is [i] pkgid[%s]", pi->pkgmgr_info);
484 if (pi->pkgmgr_info && strlen(pi->pkgmgr_info) == 0)
485 free(pi->pkgmgr_info);
490 case 'e': /* install */
493 pi->tep_path = strndup(optarg, MAX_STRLEN);
494 pi->is_tep_included = 1;
495 DBG("option is [e] tep_path[%s]", pi->tep_path);
498 case 'M': /* install */
499 if (strcmp(optarg, "tep_move") == 0)
503 DBG("option is [M] tep_move[%d]", pi->tep_move);
506 case 'd': /* uninstall */
512 pi->request_type = PKGMGR_REQ_UNINSTALL;
514 free(pi->pkgmgr_info);
515 pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
519 case 'c': /* clear */
525 pi->request_type = PKGMGR_REQ_CLEAR;
527 free(pi->pkgmgr_info);
528 pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
537 pi->request_type = PKGMGR_REQ_MOVE;
539 free(pi->pkgmgr_info);
540 pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
543 case 'r': /* reinstall */
549 pi->request_type = PKGMGR_REQ_REINSTALL;
551 free(pi->pkgmgr_info);
552 pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
555 case 't': /* move type*/
556 pi->move_type = atoi(optarg);
559 case 'p': /* caller pkgid*/
560 if (pi->caller_pkgid)
561 free(pi->caller_pkgid);
562 pi->caller_pkgid = strndup(optarg, MAX_STRLEN);
566 case 's': /* smack */
572 pi->request_type = PKGMGR_REQ_SMACK;
574 free(pi->pkgmgr_info);
575 pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
578 case 'o': /* optional data*/
579 pi->optional_data = strndup(optarg, MAX_STRLEN);
582 case 'y': /* pkgid for direct manifest installation */
584 pi->request_type = PKGMGR_REQ_MANIFEST_DIRECT_INSTALL;
585 pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
588 case 'w': /* pkgid for mount installation */
590 pi->request_type = PKGMGR_REQ_MOUNT_INSTALL;
591 pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
594 case 'b': /* recovery */
600 pi->request_type = PKGMGR_REQ_RECOVER;
602 free(pi->pkgmgr_info);
603 pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
606 case 'D': /* disable pkg */
607 pi->request_type = PKGMGR_REQ_DISABLE_PKG;
609 free(pi->pkgmgr_info);
610 pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
613 case 'A': /* enable pkg */
614 pi->request_type = PKGMGR_REQ_ENABLE_PKG;
616 free(pi->pkgmgr_info);
617 pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
621 g_target_uid = (uid_t)atoi(optarg);
622 pi->target_uid = (uid_t)atoi(optarg);
626 case '?': /* Not an option */
635 /* if target user is not set, set as tizenglobalapp user */
636 if (pi->target_uid == 0) {
637 pi->target_uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
638 g_target_uid = pi->target_uid;
644 API int pkgmgr_installer_get_request_type(pkgmgr_installer *pi)
646 CHK_PI_RET(PKGMGR_REQ_INVALID);
647 return pi->request_type;
650 API uid_t pkgmgr_installer_get_uid(pkgmgr_installer *pi)
652 CHK_PI_RET(PKGMGR_REQ_INVALID);
653 return pi->target_uid;
656 API const char *pkgmgr_installer_get_request_info(pkgmgr_installer *pi)
658 CHK_PI_RET(PKGMGR_REQ_INVALID);
659 return pi->pkgmgr_info;
662 API const char *pkgmgr_installer_get_tep_path(pkgmgr_installer *pi)
664 CHK_PI_RET(PKGMGR_REQ_INVALID);
668 API int pkgmgr_installer_get_tep_move_type(pkgmgr_installer *pi)
670 CHK_PI_RET(PKGMGR_REQ_INVALID);
674 API const char *pkgmgr_installer_get_session_id(pkgmgr_installer *pi)
676 CHK_PI_RET(PKGMGR_REQ_INVALID);
677 return pi->session_id;
680 API const char *pkgmgr_installer_get_license_path(pkgmgr_installer *pi)
682 CHK_PI_RET(PKGMGR_REQ_INVALID);
683 return pi->license_path;
686 API const char *pkgmgr_installer_get_optional_data(pkgmgr_installer *pi)
688 CHK_PI_RET(PKGMGR_REQ_INVALID);
689 return pi->optional_data;
692 API int pkgmgr_installer_is_quiet(pkgmgr_installer *pi)
697 API int pkgmgr_installer_get_move_type(pkgmgr_installer *pi)
699 CHK_PI_RET(PKGMGR_REQ_INVALID);
700 return pi->move_type;
703 API const char *pkgmgr_installer_get_caller_pkgid(pkgmgr_installer *pi)
705 CHK_PI_RET(PKGMGR_REQ_INVALID);
706 return pi->caller_pkgid;
709 API int pkgmgr_installer_get_is_preload(pkgmgr_installer *pi)
711 CHK_PI_RET(PKGMGR_REQ_INVALID);
712 return pi->is_preload;
715 API int pkgmgr_installer_get_force_removal(pkgmgr_installer *pi)
717 CHK_PI_RET(PKGMGR_REQ_INVALID);
718 return pi->force_removal;
721 API int pkgmgr_installer_send_app_uninstall_signal(pkgmgr_installer *pi,
722 const char *pkg_type,
727 ret = __send_signal_for_event(pi, pkg_type, pkgid,
728 PKGMGR_INSTALLER_APPID_KEY_STR, val);
732 API int pkgmgr_installer_set_uid(pkgmgr_installer *pi, uid_t uid)
737 pi->target_uid = uid;
738 g_target_uid = pi->target_uid;
744 pkgmgr_installer_send_app_signal(pkgmgr_installer *pi,
745 const char *pkg_type,
748 const char *key, const char *val)
753 ERR("connection is NULL");
757 r = __send_signal_for_app_event(pi, pkg_type, pkgid, appid, key, val);
763 pkgmgr_installer_send_signal(pkgmgr_installer *pi,
764 const char *pkg_type,
766 const char *key, const char *val)
771 ERR("connection is NULL");
775 if (strcmp(key, PKGMGR_INSTALLER_START_KEY_STR) == 0 &&
776 strcmp(val, PKGMGR_INSTALLER_UPGRADE_EVENT_STR) == 0)
777 pi->request_type = PKGMGR_REQ_UPGRADE;
779 r = __send_signal_for_event(pi, pkg_type, pkgid, key, val);
784 API int pkgmgr_installer_send_app_signal_for_uid(pkgmgr_installer *pi,
785 uid_t uid, const char *pkg_type, const char *pkgid,
786 const char *appid, const char *key, const char *val)
791 ERR("connection is NULL");
795 r = __send_app_signal_for_event_for_uid(pi, uid, pkg_type, pkgid, appid, key, val);
800 API int pkgmgr_installer_send_signal_for_uid(pkgmgr_installer *pi,
801 uid_t uid, const char *pkg_type, const char *pkgid,
802 const char *key, const char *val)
807 ERR("connection is NULL");
811 if (strcmp(key, PKGMGR_INSTALLER_START_KEY_STR) == 0 &&
812 strcmp(val, PKGMGR_INSTALLER_UPGRADE_EVENT_STR) == 0)
813 pi->request_type = PKGMGR_REQ_UPGRADE;
815 r = __send_signal_for_event_for_uid(pi, uid, pkg_type, pkgid, key, val);
820 API int pkgmgr_installer_set_request_type(pkgmgr_installer *pi, int request_type)
825 pi->request_type = request_type;
829 API int pkgmgr_installer_set_session_id(pkgmgr_installer *pi, const char *session_id)
831 if (pi == NULL || session_id == NULL)
834 pi->session_id = strndup(session_id, MAX_STRLEN);
838 API int pkgmgr_installer_create_certinfo_set_handle(pkgmgr_instcertinfo_h *handle)
841 ret = pkgmgrinfo_create_certinfo_set_handle(handle);
845 API int pkgmgr_installer_set_cert_value(pkgmgr_instcertinfo_h handle, pkgmgr_instcert_type cert_type, char *cert_value)
848 ret = pkgmgrinfo_set_cert_value(handle, cert_type, cert_value);
852 API int pkgmgr_installer_save_certinfo(const char *pkgid, pkgmgr_instcertinfo_h handle, uid_t uid)
855 ret = pkgmgrinfo_save_certinfo(pkgid, handle, uid);
859 API int pkgmgr_installer_destroy_certinfo_set_handle(pkgmgr_instcertinfo_h handle)
862 ret = pkgmgrinfo_destroy_certinfo_set_handle(handle);
866 API int pkgmgr_installer_delete_certinfo(const char *pkgid)
869 ret = pkgmgrinfo_delete_certinfo(pkgid);
873 API int pkgmgr_installer_info_get_target_uid(uid_t *uid)