*
*/
-
-
+#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
+#include <errno.h>
#include <getopt.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <glib.h>
#include <gio/gio.h>
+#include <tzplatform_config.h>
#include "pkgmgr_installer.h"
#include "pkgmgr_installer_config.h"
#include "pkgmgr_installer_debug.h"
-
-#include "../client/include/comm_config.h"
+#include "pkgmgr_installer_info.h"
#include <pkgmgr-info.h>
#define CHK_PI_RET(r) \
do { if (NULL == pi) return (r); } while (0)
+#define OPTVAL_PRELOAD 1000
+#define OPTVAL_FORCE_REMOVAL 1001
+#define OPTVAL_PRELOAD_RW 1002
+#define OPTVAL_NO_REMOVAL 1003
+#define OPTVAL_KEEP_RWDATA 1004
+#define OPTVAL_PARTIAL_RW 1005
+#define OPTVAL_MIGRATE_EXTIMG 1006
+
+/* Supported options */
+const char *short_opts = "k:l:i:d:c:m:t:o:r:p:s:b:e:M:y:u:w:D:A:qG";
+const struct option long_opts[] = {
+ { "session-id", 1, NULL, 'k' },
+ { "license-path", 1, NULL, 'l' },
+ { "install", 1, NULL, 'i' },
+ { "uninstall", 1, NULL, 'd' },
+ { "clear", 1, NULL, 'c' },
+ { "move", 1, NULL, 'm' },
+ { "move-type", 1, NULL, 't' },
+ { "optional-data", 0, NULL, 'o' },
+ { "reinstall", 0, NULL, 'r' },
+ { "caller-pkgid", 1, NULL, 'p' },
+ { "tep-path", 1, NULL, 'e' },
+ { "tep-move", 1, NULL, 'M' },
+ { "smack", 1, NULL, 's' },
+ { "direct-manifest-install", 1, NULL, 'y' },
+ { "mount-install", 1, NULL, 'w' },
+ { "recovery", 1, NULL, 'b' },
+ { "debug-mode", 0, NULL, 'G' },
+ { "preload", 0, NULL, OPTVAL_PRELOAD }, /* for preload RO */
+ { "force-remove", 0, NULL, OPTVAL_FORCE_REMOVAL }, /* for preload RO/RW */
+ { "preload-rw", 0, NULL, OPTVAL_PRELOAD_RW }, /* for preload RW */
+ { "no-remove", 0, NULL, OPTVAL_NO_REMOVAL }, /* for preload RW */
+ { "keep-rwdata", 0, NULL, OPTVAL_KEEP_RWDATA }, /* for preload RW */
+ { "partial-rw", 0, NULL, OPTVAL_PARTIAL_RW }, /* for preload RO */
+ { "migrate-extimg", 1, NULL, OPTVAL_MIGRATE_EXTIMG },
+ { 0, 0, 0, 0 } /* sentinel */
+};
+
struct pkgmgr_installer {
int request_type;
int move_type;
int is_tep_included;
int is_preload;
int force_removal;
+ int is_preload_rw;
+ int no_removal;
+ int keep_rwdata;
+ int partial_rw;
+ int debug_mode;
GDBusConnection *conn;
};
-static const char *__get_signal_name(pkgmgr_installer *pi, const char *key)
+static uid_t g_target_uid;
+static pkgmgr_privilege_level g_privilege_level = PM_PRIVILEGE_UNKNOWN;
+
+static const char *__get_signal_name(pkgmgr_installer *pi, const char *key,
+ const char *pkg_type)
{
if (strcmp(key, PKGMGR_INSTALLER_INSTALL_PERCENT_KEY_STR) == 0)
- return COMM_STATUS_BROADCAST_EVENT_INSTALL_PROGRESS;
+ return key;
else if (strcmp(key, PKGMGR_INSTALLER_GET_SIZE_KEY_STR) == 0)
- return COMM_STATUS_BROADCAST_EVENT_GET_SIZE;
+ return key;
else if (strcmp(key, PKGMGR_INSTALLER_APPID_KEY_STR) == 0)
- return COMM_STATUS_BROADCAST_EVENT_UNINSTALL;
+ return PKGMGR_INSTALLER_UNINSTALL_EVENT_STR;
+ else if (strcmp(pkg_type, PKGMGR_INSTALLER_CLEAR_CACHE_KEY_STR) == 0)
+ return pkg_type;
switch (pi->request_type) {
case PKGMGR_REQ_INSTALL:
- return COMM_STATUS_BROADCAST_EVENT_INSTALL;
+ case PKGMGR_REQ_MANIFEST_DIRECT_INSTALL:
+ case PKGMGR_REQ_MOUNT_INSTALL:
+ case PKGMGR_REQ_REINSTALL:
+ case PKGMGR_REQ_ENABLE_PKG:
+ case PKGMGR_REQ_RECOVER:
+ return PKGMGR_INSTALLER_INSTALL_EVENT_STR;
case PKGMGR_REQ_UNINSTALL:
- return COMM_STATUS_BROADCAST_EVENT_UNINSTALL;
+ case PKGMGR_REQ_DISABLE_PKG:
+ return PKGMGR_INSTALLER_UNINSTALL_EVENT_STR;
case PKGMGR_REQ_UPGRADE:
- return COMM_STATUS_BROADCAST_EVENT_UPGRADE;
+ return PKGMGR_INSTALLER_UPGRADE_EVENT_STR;
case PKGMGR_REQ_MOVE:
- return COMM_STATUS_BROADCAST_EVENT_MOVE;
+ return PKGMGR_INSTALLER_MOVE_EVENT_STR;
case PKGMGR_REQ_ENABLE_APP:
- return COMM_STATUS_BROADCAST_EVENT_ENABLE_APP;
+ return PKGMGR_INSTALLER_APP_ENABLE_EVENT_STR;
case PKGMGR_REQ_DISABLE_APP:
- return COMM_STATUS_BROADCAST_EVENT_DISABLE_APP;
+ return PKGMGR_INSTALLER_APP_DISABLE_EVENT_STR;
case PKGMGR_REQ_ENABLE_APP_SPLASH_SCREEN:
- return COMM_STATUS_BROADCAST_EVENT_ENABLE_APP_SPLASH_SCREEN;
+ return PKGMGR_INSTALLER_APP_ENABLE_SPLASH_SCREEN_EVENT_STR;
case PKGMGR_REQ_DISABLE_APP_SPLASH_SCREEN:
- return COMM_STATUS_BROADCAST_EVENT_DISABLE_APP_SPLASH_SCREEN;
+ return PKGMGR_INSTALLER_APP_DISABLE_SPLASH_SCREEN_EVENT_STR;
+ case PKGMGR_REQ_CLEAR:
+ return PKGMGR_INSTALLER_CLEAR_EVENT_STR;
+ case PKGMGR_REQ_GETSIZE:
+ return PKGMGR_INSTALLER_GET_SIZE_KEY_STR;
}
- ERR("cannot find type, send signal with type SIGNAL_STATUS");
+ ERR("cannot find type");
- return COMM_STATUS_BROADCAST_SIGNAL_STATUS;
+ return NULL;
}
-static int __send_signal_for_app_event(pkgmgr_installer *pi, const char *pkg_type,
- const char *pkgid, const char *appid, const char *key, const char *val)
+static int __send_signal_for_event(pkgmgr_installer *pi, const char *pkg_type,
+ const char *pkgid, const char *appid, const char *key,
+ const char *val)
{
char *sid;
const char *name;
GError *err = NULL;
- if (!pi || pi->conn == NULL || appid == NULL)
+ if (!pi || pi->conn == NULL)
return -1;
sid = pi->session_id;
if (!sid)
sid = "";
- name = __get_signal_name(pi, key);
+ name = __get_signal_name(pi, key, pkg_type);
if (name == NULL) {
ERR("unknown signal type");
return -1;
}
if (g_dbus_connection_emit_signal(pi->conn, NULL,
- COMM_STATUS_BROADCAST_OBJECT_PATH,
- COMM_STATUS_BROADCAST_INTERFACE, name,
+ PKGMGR_INSTALLER_DBUS_OBJECT_PATH,
+ PKGMGR_INSTALLER_DBUS_INTERFACE, name,
g_variant_new("(ussssss)", pi->target_uid, sid,
- pkg_type, pkgid, appid, key, val), &err)
+ pkg_type, pkgid, appid ? appid : "",
+ key, val), &err)
!= TRUE) {
ERR("failed to send dbus signal: %s", err->message);
g_error_free(err);
return 0;
}
-static int __send_signal_for_event(pkgmgr_installer *pi, const char *pkg_type,
- const char *pkgid, const char *key, const char *val)
+static int __send_signal_to_agent(uid_t uid, void *data, size_t len)
+{
+ int fd;
+ struct sockaddr_un sa;
+ int r;
+
+ fd = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0);
+ if (fd == -1) {
+ ERR("failed to create socket: %d", errno);
+ return -1;
+ }
+
+ sa.sun_family = AF_UNIX;
+ snprintf(sa.sun_path, sizeof(sa.sun_path), "/run/pkgmgr/agent/%d", uid);
+
+ r = connect(fd, (struct sockaddr *)&sa, sizeof(sa));
+ if (r == -1) {
+ ERR("failed to connect socket(%s): %d", sa.sun_path, errno);
+ close(fd);
+ return -1;
+ }
+
+ r = send(fd, data, len, MSG_NOSIGNAL);
+ if (r < 0) {
+ ERR("failed to send data: %d", errno);
+ close(fd);
+ return -1;
+ }
+
+ close(fd);
+
+ return 0;
+}
+
+static int __send_signal_for_event_for_uid(pkgmgr_installer *pi, uid_t uid,
+ const char *pkg_type, const char *pkgid, const char *appid,
+ const char *key, const char *val)
{
char *sid;
const char *name;
- GError *err = NULL;
+ size_t name_size;
+ GVariant *gv;
+ gsize gv_len;
+ gpointer gv_data;
+ void *data;
+ void *ptr;
+ size_t data_len;
if (!pi || pi->conn == NULL)
return -1;
if (!sid)
sid = "";
- name = __get_signal_name(pi, key);
+ data_len = sizeof(size_t) + sizeof(gsize);
+
+ name = __get_signal_name(pi, key, pkg_type);
if (name == NULL) {
ERR("unknown signal type");
return -1;
}
-
- if (g_dbus_connection_emit_signal(pi->conn, NULL,
- COMM_STATUS_BROADCAST_OBJECT_PATH,
- COMM_STATUS_BROADCAST_INTERFACE, name,
- g_variant_new("(ussssss)", pi->target_uid, sid,
- pkg_type, pkgid, "", key, val), &err)
- != TRUE) {
- ERR("failed to send dbus signal: %s", err->message);
- g_error_free(err);
+ /* including null byte */
+ name_size = strlen(name) + 1;
+ data_len += name_size;
+
+ gv = g_variant_new("(ussssss)", pi->target_uid, sid,
+ pkg_type, pkgid, appid ? appid : "", key, val);
+ if (gv == NULL) {
+ ERR("failed to create GVariant instance");
+ return -1;
+ }
+ gv_len = g_variant_get_size(gv);
+ gv_data = g_malloc(gv_len);
+ g_variant_store(gv, gv_data);
+ g_variant_unref(gv);
+ data_len += gv_len;
+
+ data = malloc(data_len);
+ ptr = data;
+ memcpy(ptr, &name_size, sizeof(size_t));
+ ptr += sizeof(size_t);
+ memcpy(ptr, &gv_len, sizeof(gsize));
+ ptr += sizeof(gsize);
+ memcpy(ptr, name, name_size);
+ ptr += name_size;
+ memcpy(ptr, gv_data, gv_len);
+ g_free(gv_data);
+
+ if (__send_signal_to_agent(uid, data, data_len)) {
+ ERR("failed to send signal to agent");
+ free(data);
return -1;
}
+ free(data);
+
return 0;
}
int mode = 0;
pi->target_uid = getuid();
+ g_target_uid = pi->target_uid;
while (1) {
c = getopt_long(argc, argv, short_opts, long_opts, &opt_idx);
/* printf("c=%d %c\n", c, c); //debug */
switch (c) {
case OPTVAL_PRELOAD: /* request for preload app */
pi->is_preload = 1;
- DBG("preload request [%d]", pi->is_preload );
+ DBG("preload request [%d]", pi->is_preload);
break;
case OPTVAL_FORCE_REMOVAL: /* request for force-remove */
pi->force_removal = 1;
- DBG("force-remove request [%d]", pi->force_removal );
+ DBG("force-remove request [%d]", pi->force_removal);
+ break;
+ case OPTVAL_PRELOAD_RW: /* request for preload-rw app */
+ pi->is_preload_rw = 1;
+ DBG("preload-rw request [%d]", pi->is_preload_rw);
+ break;
+ case OPTVAL_NO_REMOVAL: /* request for no-remove */
+ pi->no_removal = 1;
+ DBG("no-remove request [%d]", pi->no_removal);
+ break;
+ case OPTVAL_KEEP_RWDATA: /* request for keep-rwdata */
+ pi->keep_rwdata = 1;
+ DBG("keep-rwdata request [%d]", pi->keep_rwdata);
+ break;
+ case OPTVAL_PARTIAL_RW: /* request for partial-rw */
+ pi->partial_rw = 1;
+ DBG("partial-rw request [%d]", pi->partial_rw);
+ break;
+ case OPTVAL_MIGRATE_EXTIMG:
+ /* request for legacy extimg migration */
+ if (mode) {
+ r = -EINVAL;
+ goto RET;
+ }
+ mode = OPTVAL_MIGRATE_EXTIMG;
+ pi->request_type = PKGMGR_REQ_MIGRATE_EXTIMG;
+ if (pi->pkgmgr_info)
+ free(pi->pkgmgr_info);
+ pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
+ DBG("legacy extimg migration requested");
break;
case 'k': /* session id */
if (pi->session_id)
if (pi->pkgmgr_info)
free(pi->pkgmgr_info);
pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
- DBG("option is [i] pkgid[%s]", pi->pkgmgr_info );
- if (pi->pkgmgr_info && strlen(pi->pkgmgr_info)==0){
+ DBG("option is [i] pkgid[%s]", pi->pkgmgr_info);
+ if (pi->pkgmgr_info && strlen(pi->pkgmgr_info) == 0)
free(pi->pkgmgr_info);
- }else{
+ else
mode = 'i';
- }
break;
case 'e': /* install */
pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
break;
+ case 'w': /* pkgid for mount installation */
+ mode = 'w';
+ pi->request_type = PKGMGR_REQ_MOUNT_INSTALL;
+ pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
+ break;
+
case 'b': /* recovery */
if (mode) {
r = -EINVAL;
pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
break;
+ case 'D': /* disable pkg */
+ pi->request_type = PKGMGR_REQ_DISABLE_PKG;
+ if (pi->pkgmgr_info)
+ free(pi->pkgmgr_info);
+ pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
+ break;
+
+ case 'A': /* enable pkg */
+ pi->request_type = PKGMGR_REQ_ENABLE_PKG;
+ if (pi->pkgmgr_info)
+ free(pi->pkgmgr_info);
+ pi->pkgmgr_info = strndup(optarg, MAX_STRLEN);
+ break;
+
+ case 'u': /* uid */
+ g_target_uid = (uid_t)atoi(optarg);
+ pi->target_uid = (uid_t)atoi(optarg);
+ break;
+
+ case 'G': /* debug mode */
+ pi->debug_mode = 1;
+ break;
+
/* Otherwise */
case '?': /* Not an option */
break;
}
}
+ /* if target user is not set, set as tizenglobalapp user */
+ if (pi->target_uid == 0) {
+ pi->target_uid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
+ g_target_uid = pi->target_uid;
+ }
RET:
return r;
}
return pi->request_type;
}
+API uid_t pkgmgr_installer_get_uid(pkgmgr_installer *pi)
+{
+ CHK_PI_RET(PKGMGR_REQ_INVALID);
+ return pi->target_uid;
+}
+
API const char *pkgmgr_installer_get_request_info(pkgmgr_installer *pi)
{
CHK_PI_RET(PKGMGR_REQ_INVALID);
return pi->force_removal;
}
+API int pkgmgr_installer_get_is_preload_rw(pkgmgr_installer *pi)
+{
+ CHK_PI_RET(PKGMGR_REQ_INVALID);
+ return pi->is_preload_rw;
+}
+
+API int pkgmgr_installer_get_no_removal(pkgmgr_installer *pi)
+{
+ CHK_PI_RET(PKGMGR_REQ_INVALID);
+ return pi->no_removal;
+}
+
+API int pkgmgr_installer_get_keep_rwdata(pkgmgr_installer *pi)
+{
+ CHK_PI_RET(PKGMGR_REQ_INVALID);
+ return pi->keep_rwdata;
+}
+
+API int pkgmgr_installer_get_partial_rw(pkgmgr_installer *pi)
+{
+ CHK_PI_RET(PKGMGR_REQ_INVALID);
+ return pi->partial_rw;
+}
+
+API int pkgmgr_installer_get_debug_mode(pkgmgr_installer *pi)
+{
+ CHK_PI_RET(PKGMGR_REQ_INVALID);
+ return pi->debug_mode;
+}
+
API int pkgmgr_installer_send_app_uninstall_signal(pkgmgr_installer *pi,
const char *pkg_type,
const char *pkgid,
const char *val)
{
int ret = 0;
- ret = __send_signal_for_event(pi, pkg_type, pkgid,
+ ret = __send_signal_for_event(pi, pkg_type, pkgid, NULL,
+ PKGMGR_INSTALLER_APPID_KEY_STR, val);
+ return ret;
+}
+
+API int pkgmgr_installer_send_app_uninstall_signal_for_uid(
+ pkgmgr_installer *pi, uid_t uid, const char *pkg_type,
+ const char *pkgid, const char *val)
+{
+ int ret = 0;
+ ret = __send_signal_for_event_for_uid(pi, uid, pkg_type, pkgid, NULL,
PKGMGR_INSTALLER_APPID_KEY_STR, val);
return ret;
}
return -1;
pi->target_uid = uid;
+ g_target_uid = pi->target_uid;
return 0;
}
return -1;
}
- r = __send_signal_for_app_event(pi, pkg_type, pkgid, appid, key, val);
+ r = __send_signal_for_event(pi, pkg_type, pkgid, appid, key, val);
return r;
}
return -1;
}
- if (strcmp(key, PKGMGR_INSTALLER_UPGRADE_EVENT_STR) == 0)
+ if (strcmp(key, PKGMGR_INSTALLER_START_KEY_STR) == 0 &&
+ strcmp(val, PKGMGR_INSTALLER_UPGRADE_EVENT_STR) == 0)
pi->request_type = PKGMGR_REQ_UPGRADE;
- r = __send_signal_for_event(pi, pkg_type, pkgid, key, val);
+ r = __send_signal_for_event(pi, pkg_type, pkgid, NULL, key, val);
+
+ return r;
+}
+
+API int pkgmgr_installer_send_app_signal_for_uid(pkgmgr_installer *pi,
+ uid_t uid, const char *pkg_type, const char *pkgid,
+ const char *appid, const char *key, const char *val)
+{
+ int r = 0;
+
+ if (!pi->conn) {
+ ERR("connection is NULL");
+ return -1;
+ }
+
+ r = __send_signal_for_event_for_uid(pi, uid, pkg_type, pkgid, appid,
+ key, val);
+
+ return r;
+}
+
+API int pkgmgr_installer_send_signal_for_uid(pkgmgr_installer *pi,
+ uid_t uid, const char *pkg_type, const char *pkgid,
+ const char *key, const char *val)
+{
+ int r = 0;
+
+ if (!pi->conn) {
+ ERR("connection is NULL");
+ return -1;
+ }
+
+ if (strcmp(key, PKGMGR_INSTALLER_START_KEY_STR) == 0 &&
+ strcmp(val, PKGMGR_INSTALLER_UPGRADE_EVENT_STR) == 0)
+ pi->request_type = PKGMGR_REQ_UPGRADE;
+
+ r = __send_signal_for_event_for_uid(pi, uid, pkg_type, pkgid, NULL,
+ key, val);
return r;
}
ret = pkgmgrinfo_delete_certinfo(pkgid);
return ret;
}
+
+API int pkgmgr_installer_set_privilege_level(pkgmgr_privilege_level level)
+{
+ g_privilege_level = level;
+
+ return 0;
+}
+
+API int pkgmgr_installer_info_get_target_uid(uid_t *uid)
+{
+ *uid = g_target_uid;
+
+ return 0;
+}
+
+API int pkgmgr_installer_info_get_privilege_level(pkgmgr_privilege_level *level)
+{
+ *level = g_privilege_level;
+
+ return 0;
+}