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
62 /* Supported options */
63 const char *short_opts = "k:l:i:d:c:m:t:o:r:p:s:b:e:M:y:u:w:D:A:qG";
64 const struct option long_opts[] = {
65 { "session-id", 1, NULL, 'k' },
66 { "license-path", 1, NULL, 'l' },
67 { "install", 1, NULL, 'i' },
68 { "uninstall", 1, NULL, 'd' },
69 { "clear", 1, NULL, 'c' },
70 { "move", 1, NULL, 'm' },
71 { "move-type", 1, NULL, 't' },
72 { "optional-data", 0, NULL, 'o' },
73 { "reinstall", 0, NULL, 'r' },
74 { "caller-pkgid", 1, NULL, 'p' },
75 { "tep-path", 1, NULL, 'e' },
76 { "tep-move", 1, NULL, 'M' },
77 { "smack", 1, NULL, 's' },
78 { "direct-manifest-install", 1, NULL, 'y' },
79 { "mount-install", 1, NULL, 'w' },
80 { "recovery", 1, NULL, 'b' },
81 { "debug-mode", 0, NULL, 'G' },
82 { "preload", 0, NULL, OPTVAL_PRELOAD }, /* for preload RO */
83 { "force-remove", 0, NULL, OPTVAL_FORCE_REMOVAL }, /* for preload RO/RW */
84 { "preload-rw", 0, NULL, OPTVAL_PRELOAD_RW }, /* for preload RW */
85 { "no-remove", 0, NULL, OPTVAL_NO_REMOVAL }, /* for preload RW */
86 { "keep-rwdata", 0, NULL, OPTVAL_KEEP_RWDATA }, /* for preload RW */
87 { "partial-rw", 0, NULL, OPTVAL_PARTIAL_RW }, /* for preload RO */
88 { 0, 0, 0, 0 } /* sentinel */
91 struct pkgmgr_installer {
110 GDBusConnection *conn;
113 static uid_t g_target_uid;
115 static const char *__get_signal_name(pkgmgr_installer *pi, const char *key,
116 const char *pkg_type)
118 if (strcmp(key, PKGMGR_INSTALLER_INSTALL_PERCENT_KEY_STR) == 0)
120 else if (strcmp(key, PKGMGR_INSTALLER_GET_SIZE_KEY_STR) == 0)
122 else if (strcmp(key, PKGMGR_INSTALLER_APPID_KEY_STR) == 0)
123 return PKGMGR_INSTALLER_UNINSTALL_EVENT_STR;
124 else if (strcmp(pkg_type, PKGMGR_INSTALLER_CLEAR_CACHE_KEY_STR) == 0)
127 switch (pi->request_type) {
128 case PKGMGR_REQ_INSTALL:
129 case PKGMGR_REQ_MANIFEST_DIRECT_INSTALL:
130 case PKGMGR_REQ_MOUNT_INSTALL:
131 case PKGMGR_REQ_REINSTALL:
132 case PKGMGR_REQ_ENABLE_PKG:
133 case PKGMGR_REQ_RECOVER:
134 return PKGMGR_INSTALLER_INSTALL_EVENT_STR;
135 case PKGMGR_REQ_UNINSTALL:
136 case PKGMGR_REQ_DISABLE_PKG:
137 return PKGMGR_INSTALLER_UNINSTALL_EVENT_STR;
138 case PKGMGR_REQ_UPGRADE:
139 return PKGMGR_INSTALLER_UPGRADE_EVENT_STR;
140 case PKGMGR_REQ_MOVE:
141 return PKGMGR_INSTALLER_MOVE_EVENT_STR;
142 case PKGMGR_REQ_ENABLE_APP:
143 return PKGMGR_INSTALLER_APP_ENABLE_EVENT_STR;
144 case PKGMGR_REQ_DISABLE_APP:
145 return PKGMGR_INSTALLER_APP_DISABLE_EVENT_STR;
146 case PKGMGR_REQ_ENABLE_APP_SPLASH_SCREEN:
147 return PKGMGR_INSTALLER_APP_ENABLE_SPLASH_SCREEN_EVENT_STR;
148 case PKGMGR_REQ_DISABLE_APP_SPLASH_SCREEN:
149 return PKGMGR_INSTALLER_APP_DISABLE_SPLASH_SCREEN_EVENT_STR;
150 case PKGMGR_REQ_CLEAR:
151 return PKGMGR_INSTALLER_CLEAR_EVENT_STR;
152 case PKGMGR_REQ_GETSIZE:
153 return PKGMGR_INSTALLER_GET_SIZE_KEY_STR;
156 ERR("cannot find type");
161 static int __send_signal_for_event(pkgmgr_installer *pi, const char *pkg_type,
162 const char *pkgid, const char *appid, const char *key,
169 if (!pi || pi->conn == NULL)
172 sid = pi->session_id;
176 name = __get_signal_name(pi, key, pkg_type);
178 ERR("unknown signal type");
182 if (g_dbus_connection_emit_signal(pi->conn, NULL,
183 PKGMGR_INSTALLER_DBUS_OBJECT_PATH,
184 PKGMGR_INSTALLER_DBUS_INTERFACE, name,
185 g_variant_new("(ussssss)", pi->target_uid, sid,
186 pkg_type, pkgid, appid ? appid : "",
189 ERR("failed to send dbus signal: %s", err->message);
197 static int __send_signal_to_agent(uid_t uid, void *data, size_t len)
200 struct sockaddr_un sa;
203 fd = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0);
205 ERR("failed to create socket: %d", errno);
209 sa.sun_family = AF_UNIX;
210 snprintf(sa.sun_path, sizeof(sa.sun_path), "/run/pkgmgr/agent/%d", uid);
212 r = connect(fd, (struct sockaddr *)&sa, sizeof(sa));
214 ERR("failed to connect socket(%s): %d", sa.sun_path, errno);
219 r = send(fd, data, len, 0);
221 ERR("failed to send data: %d", errno);
231 static int __send_signal_for_event_for_uid(pkgmgr_installer *pi, uid_t uid,
232 const char *pkg_type, const char *pkgid, const char *appid,
233 const char *key, const char *val)
245 if (!pi || pi->conn == NULL)
248 sid = pi->session_id;
252 data_len = sizeof(size_t) + sizeof(gsize);
254 name = __get_signal_name(pi, key, pkg_type);
256 ERR("unknown signal type");
259 /* including null byte */
260 name_size = strlen(name) + 1;
261 data_len += name_size;
263 gv = g_variant_new("(ussssss)", pi->target_uid, sid,
264 pkg_type, pkgid, appid ? appid : "", key, val);
266 ERR("failed to create GVariant instance");
269 gv_len = g_variant_get_size(gv);
270 gv_data = g_malloc(gv_len);
271 g_variant_store(gv, gv_data);
275 data = malloc(data_len);
277 memcpy(ptr, &name_size, sizeof(size_t));
278 ptr += sizeof(size_t);
279 memcpy(ptr, &gv_len, sizeof(gsize));
280 ptr += sizeof(gsize);
281 memcpy(ptr, name, name_size);
283 memcpy(ptr, gv_data, gv_len);
286 if (__send_signal_to_agent(uid, data, data_len)) {
287 ERR("failed to send signal to agent");
297 API pkgmgr_installer *pkgmgr_installer_new(void)
299 pkgmgr_installer *pi;
302 pi = calloc(1, sizeof(struct pkgmgr_installer));
306 pi->conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);
307 if (pi->conn == NULL) {
308 ERR("failed to get bus: %s", err->message);
316 pi->request_type = PKGMGR_REQ_INVALID;
321 API pkgmgr_installer *pkgmgr_installer_offline_new(void)
323 pkgmgr_installer *pi;
325 pi = calloc(1, sizeof(struct pkgmgr_installer));
331 pi->request_type = PKGMGR_REQ_INVALID;
336 API int pkgmgr_installer_free(pkgmgr_installer *pi)
342 free(pi->pkgmgr_info);
344 free(pi->session_id);
345 if (pi->optional_data)
346 free(pi->optional_data);
347 if (pi->caller_pkgid)
348 free(pi->caller_pkgid);
353 g_dbus_connection_flush_sync(pi->conn, NULL, NULL);
354 g_object_unref(pi->conn);
363 pkgmgr_installer_receive_request(pkgmgr_installer *pi,
364 const int argc, char **argv)
371 optind = 1; /* Initialize optind to clear prev. index */
376 pi->target_uid = getuid();
377 g_target_uid = pi->target_uid;
379 c = getopt_long(argc, argv, short_opts, long_opts, &opt_idx);
380 /* printf("c=%d %c\n", c, c); //debug */
382 break; /* Parse is end */
384 case OPTVAL_PRELOAD: /* request for preload app */
386 DBG("preload request [%d]", pi->is_preload);
388 case OPTVAL_FORCE_REMOVAL: /* request for force-remove */
389 pi->force_removal = 1;
390 DBG("force-remove request [%d]", pi->force_removal);
392 case OPTVAL_PRELOAD_RW: /* request for preload-rw app */
393 pi->is_preload_rw = 1;
394 DBG("preload-rw request [%d]", pi->is_preload_rw);
396 case OPTVAL_NO_REMOVAL: /* request for no-remove */
398 DBG("no-remove request [%d]", pi->no_removal);
400 case OPTVAL_KEEP_RWDATA: /* request for keep-rwdata */
402 DBG("keep-rwdata request [%d]", pi->keep_rwdata);
404 case OPTVAL_PARTIAL_RW: /* request for partial-rw */
406 DBG("partial-rw request [%d]", pi->partial_rw);
408 case 'k': /* session id */
410 free(pi->session_id);
411 pi->session_id = strndup(optarg, MAX_STRLEN);
414 case 'l': /* license path */
415 if (pi->license_path)
416 free(pi->license_path);
417 pi->license_path = strndup(optarg, MAX_STRLEN);
420 case 'i': /* install */
426 pi->request_type = PKGMGR_REQ_INSTALL;
428 free(pi->pkgmgr_info);
429 pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
430 DBG("option is [i] pkgid[%s]", pi->pkgmgr_info);
431 if (pi->pkgmgr_info && strlen(pi->pkgmgr_info) == 0)
432 free(pi->pkgmgr_info);
437 case 'e': /* install */
440 pi->tep_path = strndup(optarg, MAX_STRLEN);
441 pi->is_tep_included = 1;
442 DBG("option is [e] tep_path[%s]", pi->tep_path);
445 case 'M': /* install */
446 if (strcmp(optarg, "tep_move") == 0)
450 DBG("option is [M] tep_move[%d]", pi->tep_move);
453 case 'd': /* uninstall */
459 pi->request_type = PKGMGR_REQ_UNINSTALL;
461 free(pi->pkgmgr_info);
462 pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
466 case 'c': /* clear */
472 pi->request_type = PKGMGR_REQ_CLEAR;
474 free(pi->pkgmgr_info);
475 pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
484 pi->request_type = PKGMGR_REQ_MOVE;
486 free(pi->pkgmgr_info);
487 pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
490 case 'r': /* reinstall */
496 pi->request_type = PKGMGR_REQ_REINSTALL;
498 free(pi->pkgmgr_info);
499 pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
502 case 't': /* move type*/
503 pi->move_type = atoi(optarg);
506 case 'p': /* caller pkgid*/
507 if (pi->caller_pkgid)
508 free(pi->caller_pkgid);
509 pi->caller_pkgid = strndup(optarg, MAX_STRLEN);
513 case 's': /* smack */
519 pi->request_type = PKGMGR_REQ_SMACK;
521 free(pi->pkgmgr_info);
522 pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
525 case 'o': /* optional data*/
526 pi->optional_data = strndup(optarg, MAX_STRLEN);
529 case 'y': /* pkgid for direct manifest installation */
531 pi->request_type = PKGMGR_REQ_MANIFEST_DIRECT_INSTALL;
532 pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
535 case 'w': /* pkgid for mount installation */
537 pi->request_type = PKGMGR_REQ_MOUNT_INSTALL;
538 pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
541 case 'b': /* recovery */
547 pi->request_type = PKGMGR_REQ_RECOVER;
549 free(pi->pkgmgr_info);
550 pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
553 case 'D': /* disable pkg */
554 pi->request_type = PKGMGR_REQ_DISABLE_PKG;
556 free(pi->pkgmgr_info);
557 pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
560 case 'A': /* enable pkg */
561 pi->request_type = PKGMGR_REQ_ENABLE_PKG;
563 free(pi->pkgmgr_info);
564 pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
568 g_target_uid = (uid_t)atoi(optarg);
569 pi->target_uid = (uid_t)atoi(optarg);
572 case 'G': /* debug mode */
577 case '?': /* Not an option */
586 /* if target user is not set, set as tizenglobalapp user */
587 if (pi->target_uid == 0) {
588 pi->target_uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
589 g_target_uid = pi->target_uid;
595 API int pkgmgr_installer_get_request_type(pkgmgr_installer *pi)
597 CHK_PI_RET(PKGMGR_REQ_INVALID);
598 return pi->request_type;
601 API uid_t pkgmgr_installer_get_uid(pkgmgr_installer *pi)
603 CHK_PI_RET(PKGMGR_REQ_INVALID);
604 return pi->target_uid;
607 API const char *pkgmgr_installer_get_request_info(pkgmgr_installer *pi)
609 CHK_PI_RET(PKGMGR_REQ_INVALID);
610 return pi->pkgmgr_info;
613 API const char *pkgmgr_installer_get_tep_path(pkgmgr_installer *pi)
615 CHK_PI_RET(PKGMGR_REQ_INVALID);
619 API int pkgmgr_installer_get_tep_move_type(pkgmgr_installer *pi)
621 CHK_PI_RET(PKGMGR_REQ_INVALID);
625 API const char *pkgmgr_installer_get_session_id(pkgmgr_installer *pi)
627 CHK_PI_RET(PKGMGR_REQ_INVALID);
628 return pi->session_id;
631 API const char *pkgmgr_installer_get_license_path(pkgmgr_installer *pi)
633 CHK_PI_RET(PKGMGR_REQ_INVALID);
634 return pi->license_path;
637 API const char *pkgmgr_installer_get_optional_data(pkgmgr_installer *pi)
639 CHK_PI_RET(PKGMGR_REQ_INVALID);
640 return pi->optional_data;
643 API int pkgmgr_installer_is_quiet(pkgmgr_installer *pi)
648 API int pkgmgr_installer_get_move_type(pkgmgr_installer *pi)
650 CHK_PI_RET(PKGMGR_REQ_INVALID);
651 return pi->move_type;
654 API const char *pkgmgr_installer_get_caller_pkgid(pkgmgr_installer *pi)
656 CHK_PI_RET(PKGMGR_REQ_INVALID);
657 return pi->caller_pkgid;
660 API int pkgmgr_installer_get_is_preload(pkgmgr_installer *pi)
662 CHK_PI_RET(PKGMGR_REQ_INVALID);
663 return pi->is_preload;
666 API int pkgmgr_installer_get_force_removal(pkgmgr_installer *pi)
668 CHK_PI_RET(PKGMGR_REQ_INVALID);
669 return pi->force_removal;
672 API int pkgmgr_installer_get_is_preload_rw(pkgmgr_installer *pi)
674 CHK_PI_RET(PKGMGR_REQ_INVALID);
675 return pi->is_preload_rw;
678 API int pkgmgr_installer_get_no_removal(pkgmgr_installer *pi)
680 CHK_PI_RET(PKGMGR_REQ_INVALID);
681 return pi->no_removal;
684 API int pkgmgr_installer_get_keep_rwdata(pkgmgr_installer *pi)
686 CHK_PI_RET(PKGMGR_REQ_INVALID);
687 return pi->keep_rwdata;
690 API int pkgmgr_installer_get_partial_rw(pkgmgr_installer *pi)
692 CHK_PI_RET(PKGMGR_REQ_INVALID);
693 return pi->partial_rw;
696 API int pkgmgr_installer_get_debug_mode(pkgmgr_installer *pi)
698 CHK_PI_RET(PKGMGR_REQ_INVALID);
699 return pi->debug_mode;
702 API int pkgmgr_installer_send_app_uninstall_signal(pkgmgr_installer *pi,
703 const char *pkg_type,
708 ret = __send_signal_for_event(pi, pkg_type, pkgid, NULL,
709 PKGMGR_INSTALLER_APPID_KEY_STR, val);
713 API int pkgmgr_installer_send_app_uninstall_signal_for_uid(
714 pkgmgr_installer *pi, uid_t uid, const char *pkg_type,
715 const char *pkgid, const char *val)
718 ret = __send_signal_for_event_for_uid(pi, uid, pkg_type, pkgid, NULL,
719 PKGMGR_INSTALLER_APPID_KEY_STR, val);
723 API int pkgmgr_installer_set_uid(pkgmgr_installer *pi, uid_t uid)
728 pi->target_uid = uid;
729 g_target_uid = pi->target_uid;
735 pkgmgr_installer_send_app_signal(pkgmgr_installer *pi,
736 const char *pkg_type,
739 const char *key, const char *val)
744 ERR("connection is NULL");
748 r = __send_signal_for_event(pi, pkg_type, pkgid, appid, key, val);
754 pkgmgr_installer_send_signal(pkgmgr_installer *pi,
755 const char *pkg_type,
757 const char *key, const char *val)
762 ERR("connection is NULL");
766 if (strcmp(key, PKGMGR_INSTALLER_START_KEY_STR) == 0 &&
767 strcmp(val, PKGMGR_INSTALLER_UPGRADE_EVENT_STR) == 0)
768 pi->request_type = PKGMGR_REQ_UPGRADE;
770 r = __send_signal_for_event(pi, pkg_type, pkgid, NULL, key, val);
775 API int pkgmgr_installer_send_app_signal_for_uid(pkgmgr_installer *pi,
776 uid_t uid, const char *pkg_type, const char *pkgid,
777 const char *appid, const char *key, const char *val)
782 ERR("connection is NULL");
786 r = __send_signal_for_event_for_uid(pi, uid, pkg_type, pkgid, appid,
792 API int pkgmgr_installer_send_signal_for_uid(pkgmgr_installer *pi,
793 uid_t uid, const char *pkg_type, const char *pkgid,
794 const char *key, const char *val)
799 ERR("connection is NULL");
803 if (strcmp(key, PKGMGR_INSTALLER_START_KEY_STR) == 0 &&
804 strcmp(val, PKGMGR_INSTALLER_UPGRADE_EVENT_STR) == 0)
805 pi->request_type = PKGMGR_REQ_UPGRADE;
807 r = __send_signal_for_event_for_uid(pi, uid, pkg_type, pkgid, NULL,
813 API int pkgmgr_installer_set_request_type(pkgmgr_installer *pi, int request_type)
818 pi->request_type = request_type;
822 API int pkgmgr_installer_set_session_id(pkgmgr_installer *pi, const char *session_id)
824 if (pi == NULL || session_id == NULL)
827 pi->session_id = strndup(session_id, MAX_STRLEN);
831 API int pkgmgr_installer_create_certinfo_set_handle(pkgmgr_instcertinfo_h *handle)
834 ret = pkgmgrinfo_create_certinfo_set_handle(handle);
838 API int pkgmgr_installer_set_cert_value(pkgmgr_instcertinfo_h handle, pkgmgr_instcert_type cert_type, char *cert_value)
841 ret = pkgmgrinfo_set_cert_value(handle, cert_type, cert_value);
845 API int pkgmgr_installer_save_certinfo(const char *pkgid, pkgmgr_instcertinfo_h handle, uid_t uid)
848 ret = pkgmgrinfo_save_certinfo(pkgid, handle, uid);
852 API int pkgmgr_installer_destroy_certinfo_set_handle(pkgmgr_instcertinfo_h handle)
855 ret = pkgmgrinfo_destroy_certinfo_set_handle(handle);
859 API int pkgmgr_installer_delete_certinfo(const char *pkgid)
862 ret = pkgmgrinfo_delete_certinfo(pkgid);
866 API int pkgmgr_installer_info_get_target_uid(uid_t *uid)