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
57 #define OPTVAL_PRELOAD_RW 1002
58 #define OPTVAL_NO_REMOVAL 1003
59 #define OPTVAL_KEEP_RWDATA 1004
60 #define OPTVAL_PARTIAL_RW 1005
61 #define OPTVAL_MIGRATE_EXTIMG 1006
63 /* Supported options */
64 const char *short_opts = "k:l:i:d:c:m:t:o:r:p:s:b:e:M:y:u:w:D:A:qG";
65 const struct option long_opts[] = {
66 { "session-id", 1, NULL, 'k' },
67 { "license-path", 1, NULL, 'l' },
68 { "install", 1, NULL, 'i' },
69 { "uninstall", 1, NULL, 'd' },
70 { "clear", 1, NULL, 'c' },
71 { "move", 1, NULL, 'm' },
72 { "move-type", 1, NULL, 't' },
73 { "optional-data", 0, NULL, 'o' },
74 { "reinstall", 0, NULL, 'r' },
75 { "caller-pkgid", 1, NULL, 'p' },
76 { "tep-path", 1, NULL, 'e' },
77 { "tep-move", 1, NULL, 'M' },
78 { "smack", 1, NULL, 's' },
79 { "direct-manifest-install", 1, NULL, 'y' },
80 { "mount-install", 1, NULL, 'w' },
81 { "recovery", 1, NULL, 'b' },
82 { "debug-mode", 0, NULL, 'G' },
83 { "preload", 0, NULL, OPTVAL_PRELOAD }, /* for preload RO */
84 { "force-remove", 0, NULL, OPTVAL_FORCE_REMOVAL }, /* for preload RO/RW */
85 { "preload-rw", 0, NULL, OPTVAL_PRELOAD_RW }, /* for preload RW */
86 { "no-remove", 0, NULL, OPTVAL_NO_REMOVAL }, /* for preload RW */
87 { "keep-rwdata", 0, NULL, OPTVAL_KEEP_RWDATA }, /* for preload RW */
88 { "partial-rw", 0, NULL, OPTVAL_PARTIAL_RW }, /* for preload RO */
89 { "migrate-extimg", 1, NULL, OPTVAL_MIGRATE_EXTIMG },
90 { 0, 0, 0, 0 } /* sentinel */
93 struct pkgmgr_installer {
112 GDBusConnection *conn;
115 static uid_t g_target_uid;
116 static pkgmgr_privilege_level g_privilege_level = PM_PRIVILEGE_UNKNOWN;
118 static const char *__get_signal_name(pkgmgr_installer *pi, const char *key,
119 const char *pkg_type)
121 if (strcmp(key, PKGMGR_INSTALLER_INSTALL_PERCENT_KEY_STR) == 0)
123 else if (strcmp(key, PKGMGR_INSTALLER_GET_SIZE_KEY_STR) == 0)
125 else if (strcmp(key, PKGMGR_INSTALLER_APPID_KEY_STR) == 0)
126 return PKGMGR_INSTALLER_UNINSTALL_EVENT_STR;
127 else if (strcmp(pkg_type, PKGMGR_INSTALLER_CLEAR_CACHE_KEY_STR) == 0)
130 switch (pi->request_type) {
131 case PKGMGR_REQ_INSTALL:
132 case PKGMGR_REQ_MANIFEST_DIRECT_INSTALL:
133 case PKGMGR_REQ_MOUNT_INSTALL:
134 case PKGMGR_REQ_REINSTALL:
135 case PKGMGR_REQ_ENABLE_PKG:
136 case PKGMGR_REQ_RECOVER:
137 return PKGMGR_INSTALLER_INSTALL_EVENT_STR;
138 case PKGMGR_REQ_UNINSTALL:
139 case PKGMGR_REQ_DISABLE_PKG:
140 return PKGMGR_INSTALLER_UNINSTALL_EVENT_STR;
141 case PKGMGR_REQ_UPGRADE:
142 return PKGMGR_INSTALLER_UPGRADE_EVENT_STR;
143 case PKGMGR_REQ_MOVE:
144 return PKGMGR_INSTALLER_MOVE_EVENT_STR;
145 case PKGMGR_REQ_ENABLE_APP:
146 return PKGMGR_INSTALLER_APP_ENABLE_EVENT_STR;
147 case PKGMGR_REQ_DISABLE_APP:
148 return PKGMGR_INSTALLER_APP_DISABLE_EVENT_STR;
149 case PKGMGR_REQ_ENABLE_APP_SPLASH_SCREEN:
150 return PKGMGR_INSTALLER_APP_ENABLE_SPLASH_SCREEN_EVENT_STR;
151 case PKGMGR_REQ_DISABLE_APP_SPLASH_SCREEN:
152 return PKGMGR_INSTALLER_APP_DISABLE_SPLASH_SCREEN_EVENT_STR;
153 case PKGMGR_REQ_CLEAR:
154 return PKGMGR_INSTALLER_CLEAR_EVENT_STR;
155 case PKGMGR_REQ_GETSIZE:
156 return PKGMGR_INSTALLER_GET_SIZE_KEY_STR;
159 ERR("cannot find type");
164 static int __send_signal_for_event(pkgmgr_installer *pi, const char *pkg_type,
165 const char *pkgid, const char *appid, const char *key,
172 if (!pi || pi->conn == NULL)
175 sid = pi->session_id;
179 name = __get_signal_name(pi, key, pkg_type);
181 ERR("unknown signal type");
185 if (g_dbus_connection_emit_signal(pi->conn, NULL,
186 PKGMGR_INSTALLER_DBUS_OBJECT_PATH,
187 PKGMGR_INSTALLER_DBUS_INTERFACE, name,
188 g_variant_new("(ussssss)", pi->target_uid, sid,
189 pkg_type, pkgid, appid ? appid : "",
192 ERR("failed to send dbus signal: %s", err->message);
200 static int __send_signal_to_agent(uid_t uid, void *data, size_t len)
203 struct sockaddr_un sa;
206 fd = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0);
208 ERR("failed to create socket: %d", errno);
212 sa.sun_family = AF_UNIX;
213 snprintf(sa.sun_path, sizeof(sa.sun_path), "/run/pkgmgr/agent/%d", uid);
215 r = connect(fd, (struct sockaddr *)&sa, sizeof(sa));
217 ERR("failed to connect socket(%s): %d", sa.sun_path, errno);
222 r = send(fd, data, len, MSG_NOSIGNAL);
224 ERR("failed to send data: %d", errno);
234 static int __send_signal_for_event_for_uid(pkgmgr_installer *pi, uid_t uid,
235 const char *pkg_type, const char *pkgid, const char *appid,
236 const char *key, const char *val)
248 if (!pi || pi->conn == NULL)
251 sid = pi->session_id;
255 data_len = sizeof(size_t) + sizeof(gsize);
257 name = __get_signal_name(pi, key, pkg_type);
259 ERR("unknown signal type");
262 /* including null byte */
263 name_size = strlen(name) + 1;
264 data_len += name_size;
266 gv = g_variant_new("(ussssss)", pi->target_uid, sid,
267 pkg_type, pkgid, appid ? appid : "", key, val);
269 ERR("failed to create GVariant instance");
272 gv_len = g_variant_get_size(gv);
273 gv_data = g_malloc(gv_len);
274 g_variant_store(gv, gv_data);
278 data = malloc(data_len);
280 memcpy(ptr, &name_size, sizeof(size_t));
281 ptr += sizeof(size_t);
282 memcpy(ptr, &gv_len, sizeof(gsize));
283 ptr += sizeof(gsize);
284 memcpy(ptr, name, name_size);
286 memcpy(ptr, gv_data, gv_len);
289 if (__send_signal_to_agent(uid, data, data_len)) {
290 ERR("failed to send signal to agent");
300 API pkgmgr_installer *pkgmgr_installer_new(void)
302 pkgmgr_installer *pi;
305 pi = calloc(1, sizeof(struct pkgmgr_installer));
309 pi->conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
310 if (pi->conn == NULL) {
311 ERR("failed to get bus: %s", err->message);
319 pi->request_type = PKGMGR_REQ_INVALID;
324 API pkgmgr_installer *pkgmgr_installer_offline_new(void)
326 pkgmgr_installer *pi;
328 pi = calloc(1, sizeof(struct pkgmgr_installer));
334 pi->request_type = PKGMGR_REQ_INVALID;
339 API int pkgmgr_installer_free(pkgmgr_installer *pi)
345 free(pi->pkgmgr_info);
347 free(pi->session_id);
348 if (pi->optional_data)
349 free(pi->optional_data);
350 if (pi->caller_pkgid)
351 free(pi->caller_pkgid);
356 g_dbus_connection_flush_sync(pi->conn, NULL, NULL);
357 g_object_unref(pi->conn);
366 pkgmgr_installer_receive_request(pkgmgr_installer *pi,
367 const int argc, char **argv)
374 optind = 1; /* Initialize optind to clear prev. index */
379 pi->target_uid = getuid();
380 g_target_uid = pi->target_uid;
382 c = getopt_long(argc, argv, short_opts, long_opts, &opt_idx);
383 /* printf("c=%d %c\n", c, c); //debug */
385 break; /* Parse is end */
387 case OPTVAL_PRELOAD: /* request for preload app */
389 DBG("preload request [%d]", pi->is_preload);
391 case OPTVAL_FORCE_REMOVAL: /* request for force-remove */
392 pi->force_removal = 1;
393 DBG("force-remove request [%d]", pi->force_removal);
395 case OPTVAL_PRELOAD_RW: /* request for preload-rw app */
396 pi->is_preload_rw = 1;
397 DBG("preload-rw request [%d]", pi->is_preload_rw);
399 case OPTVAL_NO_REMOVAL: /* request for no-remove */
401 DBG("no-remove request [%d]", pi->no_removal);
403 case OPTVAL_KEEP_RWDATA: /* request for keep-rwdata */
405 DBG("keep-rwdata request [%d]", pi->keep_rwdata);
407 case OPTVAL_PARTIAL_RW: /* request for partial-rw */
409 DBG("partial-rw request [%d]", pi->partial_rw);
411 case OPTVAL_MIGRATE_EXTIMG:
412 /* request for legacy extimg migration */
417 mode = OPTVAL_MIGRATE_EXTIMG;
418 pi->request_type = PKGMGR_REQ_MIGRATE_EXTIMG;
420 free(pi->pkgmgr_info);
421 pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
422 DBG("legacy extimg migration requested");
424 case 'k': /* session id */
426 free(pi->session_id);
427 pi->session_id = strndup(optarg, MAX_STRLEN);
430 case 'l': /* license path */
431 if (pi->license_path)
432 free(pi->license_path);
433 pi->license_path = strndup(optarg, MAX_STRLEN);
436 case 'i': /* install */
442 pi->request_type = PKGMGR_REQ_INSTALL;
444 free(pi->pkgmgr_info);
445 pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
446 DBG("option is [i] pkgid[%s]", pi->pkgmgr_info);
447 if (pi->pkgmgr_info && strlen(pi->pkgmgr_info) == 0)
448 free(pi->pkgmgr_info);
453 case 'e': /* install */
456 pi->tep_path = strndup(optarg, MAX_STRLEN);
457 pi->is_tep_included = 1;
458 DBG("option is [e] tep_path[%s]", pi->tep_path);
461 case 'M': /* install */
462 if (strcmp(optarg, "tep_move") == 0)
466 DBG("option is [M] tep_move[%d]", pi->tep_move);
469 case 'd': /* uninstall */
475 pi->request_type = PKGMGR_REQ_UNINSTALL;
477 free(pi->pkgmgr_info);
478 pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
482 case 'c': /* clear */
488 pi->request_type = PKGMGR_REQ_CLEAR;
490 free(pi->pkgmgr_info);
491 pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
500 pi->request_type = PKGMGR_REQ_MOVE;
502 free(pi->pkgmgr_info);
503 pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
506 case 'r': /* reinstall */
512 pi->request_type = PKGMGR_REQ_REINSTALL;
514 free(pi->pkgmgr_info);
515 pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
518 case 't': /* move type*/
519 pi->move_type = atoi(optarg);
522 case 'p': /* caller pkgid*/
523 if (pi->caller_pkgid)
524 free(pi->caller_pkgid);
525 pi->caller_pkgid = strndup(optarg, MAX_STRLEN);
529 case 's': /* smack */
535 pi->request_type = PKGMGR_REQ_SMACK;
537 free(pi->pkgmgr_info);
538 pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
541 case 'o': /* optional data*/
542 pi->optional_data = strndup(optarg, MAX_STRLEN);
545 case 'y': /* pkgid for direct manifest installation */
547 pi->request_type = PKGMGR_REQ_MANIFEST_DIRECT_INSTALL;
548 pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
551 case 'w': /* pkgid for mount installation */
553 pi->request_type = PKGMGR_REQ_MOUNT_INSTALL;
554 pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
557 case 'b': /* recovery */
563 pi->request_type = PKGMGR_REQ_RECOVER;
565 free(pi->pkgmgr_info);
566 pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
569 case 'D': /* disable pkg */
570 pi->request_type = PKGMGR_REQ_DISABLE_PKG;
572 free(pi->pkgmgr_info);
573 pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
576 case 'A': /* enable pkg */
577 pi->request_type = PKGMGR_REQ_ENABLE_PKG;
579 free(pi->pkgmgr_info);
580 pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
584 g_target_uid = (uid_t)atoi(optarg);
585 pi->target_uid = (uid_t)atoi(optarg);
588 case 'G': /* debug mode */
593 case '?': /* Not an option */
602 /* if target user is not set, set as tizenglobalapp user */
603 if (pi->target_uid == 0) {
604 pi->target_uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
605 g_target_uid = pi->target_uid;
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_get_is_preload_rw(pkgmgr_installer *pi)
690 CHK_PI_RET(PKGMGR_REQ_INVALID);
691 return pi->is_preload_rw;
694 API int pkgmgr_installer_get_no_removal(pkgmgr_installer *pi)
696 CHK_PI_RET(PKGMGR_REQ_INVALID);
697 return pi->no_removal;
700 API int pkgmgr_installer_get_keep_rwdata(pkgmgr_installer *pi)
702 CHK_PI_RET(PKGMGR_REQ_INVALID);
703 return pi->keep_rwdata;
706 API int pkgmgr_installer_get_partial_rw(pkgmgr_installer *pi)
708 CHK_PI_RET(PKGMGR_REQ_INVALID);
709 return pi->partial_rw;
712 API int pkgmgr_installer_get_debug_mode(pkgmgr_installer *pi)
714 CHK_PI_RET(PKGMGR_REQ_INVALID);
715 return pi->debug_mode;
718 API int pkgmgr_installer_send_app_uninstall_signal(pkgmgr_installer *pi,
719 const char *pkg_type,
724 ret = __send_signal_for_event(pi, pkg_type, pkgid, NULL,
725 PKGMGR_INSTALLER_APPID_KEY_STR, val);
729 API int pkgmgr_installer_send_app_uninstall_signal_for_uid(
730 pkgmgr_installer *pi, uid_t uid, const char *pkg_type,
731 const char *pkgid, const char *val)
734 ret = __send_signal_for_event_for_uid(pi, uid, pkg_type, pkgid, NULL,
735 PKGMGR_INSTALLER_APPID_KEY_STR, val);
739 API int pkgmgr_installer_set_uid(pkgmgr_installer *pi, uid_t uid)
744 pi->target_uid = uid;
745 g_target_uid = pi->target_uid;
751 pkgmgr_installer_send_app_signal(pkgmgr_installer *pi,
752 const char *pkg_type,
755 const char *key, const char *val)
760 ERR("connection is NULL");
764 r = __send_signal_for_event(pi, pkg_type, pkgid, appid, key, val);
770 pkgmgr_installer_send_signal(pkgmgr_installer *pi,
771 const char *pkg_type,
773 const char *key, const char *val)
778 ERR("connection is NULL");
782 if (strcmp(key, PKGMGR_INSTALLER_START_KEY_STR) == 0 &&
783 strcmp(val, PKGMGR_INSTALLER_UPGRADE_EVENT_STR) == 0)
784 pi->request_type = PKGMGR_REQ_UPGRADE;
786 r = __send_signal_for_event(pi, pkg_type, pkgid, NULL, key, val);
791 API int pkgmgr_installer_send_app_signal_for_uid(pkgmgr_installer *pi,
792 uid_t uid, const char *pkg_type, const char *pkgid,
793 const char *appid, const char *key, const char *val)
798 ERR("connection is NULL");
802 r = __send_signal_for_event_for_uid(pi, uid, pkg_type, pkgid, appid,
808 API int pkgmgr_installer_send_signal_for_uid(pkgmgr_installer *pi,
809 uid_t uid, const char *pkg_type, const char *pkgid,
810 const char *key, const char *val)
815 ERR("connection is NULL");
819 if (strcmp(key, PKGMGR_INSTALLER_START_KEY_STR) == 0 &&
820 strcmp(val, PKGMGR_INSTALLER_UPGRADE_EVENT_STR) == 0)
821 pi->request_type = PKGMGR_REQ_UPGRADE;
823 r = __send_signal_for_event_for_uid(pi, uid, pkg_type, pkgid, NULL,
829 API int pkgmgr_installer_set_request_type(pkgmgr_installer *pi, int request_type)
834 pi->request_type = request_type;
838 API int pkgmgr_installer_set_session_id(pkgmgr_installer *pi, const char *session_id)
840 if (pi == NULL || session_id == NULL)
843 pi->session_id = strndup(session_id, MAX_STRLEN);
847 API int pkgmgr_installer_create_certinfo_set_handle(pkgmgr_instcertinfo_h *handle)
850 ret = pkgmgrinfo_create_certinfo_set_handle(handle);
854 API int pkgmgr_installer_set_cert_value(pkgmgr_instcertinfo_h handle, pkgmgr_instcert_type cert_type, char *cert_value)
857 ret = pkgmgrinfo_set_cert_value(handle, cert_type, cert_value);
861 API int pkgmgr_installer_save_certinfo(const char *pkgid, pkgmgr_instcertinfo_h handle, uid_t uid)
864 ret = pkgmgrinfo_save_certinfo(pkgid, handle, uid);
868 API int pkgmgr_installer_destroy_certinfo_set_handle(pkgmgr_instcertinfo_h handle)
871 ret = pkgmgrinfo_destroy_certinfo_set_handle(handle);
875 API int pkgmgr_installer_delete_certinfo(const char *pkgid)
878 ret = pkgmgrinfo_delete_certinfo(pkgid);
882 API int pkgmgr_installer_set_privilege_level(pkgmgr_privilege_level level)
884 g_privilege_level = level;
889 API int pkgmgr_installer_info_get_target_uid(uid_t *uid)
896 API int pkgmgr_installer_info_get_privilege_level(pkgmgr_privilege_level *level)
898 *level = g_privilege_level;