Fix bug on handling request args
[platform/core/appfw/pkgmgr-server.git] / src / request.c
index 7fb6e20..0c3d41f 100644 (file)
@@ -78,6 +78,18 @@ static const char instropection_xml[] =
        "      <arg type='i' name='ret' direction='out'/>"
        "      <arg type='s' name='reqkey' direction='out'/>"
        "    </method>"
+       "    <method name='enable_apps'>"
+       "      <arg type='u' name='uid' direction='in'/>"
+       "      <arg type='as' name='appids' direction='in'/>"
+       "      <arg type='i' name='ret' direction='out'/>"
+       "      <arg type='s' name='reqkey' direction='out'/>"
+       "    </method>"
+       "    <method name='disable_apps'>"
+       "      <arg type='u' name='uid' direction='in'/>"
+       "      <arg type='as' name='appids' direction='in'/>"
+       "      <arg type='i' name='ret' direction='out'/>"
+       "      <arg type='s' name='reqkey' direction='out'/>"
+       "    </method>"
        "    <method name='enable_global_app_for_uid'>"
        "      <arg type='u' name='uid' direction='in'/>"
        "      <arg type='s' name='appid' direction='in'/>"
@@ -97,6 +109,13 @@ static const char instropection_xml[] =
        "      <arg type='i' name='ret' direction='out'/>"
        "      <arg type='s' name='reqkey' direction='out'/>"
        "    </method>"
+       "    <method name='getsize_sync'>"
+       "      <arg type='u' name='uid' direction='in'/>"
+       "      <arg type='s' name='pkgid' direction='in'/>"
+       "      <arg type='i' name='get_type' direction='in'/>"
+       "      <arg type='i' name='ret' direction='out'/>"
+       "      <arg type='x' name='size_info' direction='out'/>"
+       "    </method>"
        "    <method name='cleardata'>"
        "      <arg type='u' name='uid' direction='in'/>"
        "      <arg type='s' name='pkgid' direction='in'/>"
@@ -168,6 +187,11 @@ static const char instropection_xml[] =
        "      <arg type='s' name='label' direction='in'/>"
        "      <arg type='i' name='ret' direction='out'/>"
        "    </method>"
+       "    <method name='migrate_external_image'>"
+       "      <arg type='u' name='uid' direction='in'/>"
+       "      <arg type='s' name='pkgid' direction='in'/>"
+       "      <arg type='i' name='ret' direction='out'/>"
+       "    </method>"
        "  </interface>"
        "</node>";
 static GDBusNodeInfo *instropection_data;
@@ -190,7 +214,7 @@ static char *__generate_reqkey(const char *pkgid)
        size = strlen(pkgid) + strlen(timestr) + 2;
        str_req_key = (char *)calloc(size, sizeof(char));
        if (str_req_key == NULL) {
-               DBG("calloc failed");
+               ERR("calloc failed");
                return NULL;
        }
        snprintf(str_req_key, size, "%s_%s", pkgid, timestr);
@@ -235,7 +259,6 @@ static int __is_admin_user(uid_t uid)
        return 1;
 }
 
-#define REGULAR_USER 5000
 static int __check_caller_permission(uid_t uid,
                GDBusMethodInvocation *invocation, GVariant *parameters)
 {
@@ -282,7 +305,7 @@ static int __handle_request_install(uid_t caller_uid,
        uid_t target_uid = (uid_t)-1;
        char *arg_pkgtype = NULL;
        const char *pkgtype;
-       char *pkgpath = NULL;
+       const char *pkgpath = NULL;
        char *args = NULL;
        char *reqkey = NULL;
        gchar **tmp_args = NULL;
@@ -291,6 +314,7 @@ static int __handle_request_install(uid_t caller_uid,
        GVariant *value;
        int i = 0;
        int len = 0;
+       size_t s = 0;
 
        g_variant_get(parameters, "(u&s&s@as)", &target_uid, &arg_pkgtype,
                        &pkgpath, &value);
@@ -309,9 +333,12 @@ static int __handle_request_install(uid_t caller_uid,
        }
 
        for (i = 0; i < args_count; i++) {
-               strncat(args, tmp_args[i], strlen(tmp_args[i]));
-               if (i != args_count - 1)
-                       strncat(args, " ", strlen(" "));
+               strncat(args, tmp_args[i], len - s - 1);
+               s += strlen(tmp_args[i]);
+               if (i != args_count - 1) {
+                       strncat(args, " ", len - s - 1);
+                       s += strlen(" ");
+               }
        }
 
        if (target_uid == (uid_t)-1 || pkgpath == NULL) {
@@ -321,6 +348,7 @@ static int __handle_request_install(uid_t caller_uid,
                goto catch;
        }
 
+       pkgpath = _get_adjusted_pkgpath(pkgpath, caller_uid);
        pkgtype = _get_pkgtype_from_file(pkgpath);
        if (!pkgtype && arg_pkgtype && strlen(arg_pkgtype))
                pkgtype = (const char *)arg_pkgtype;
@@ -371,7 +399,7 @@ static int __handle_request_mount_install(uid_t caller_uid,
        uid_t target_uid = (uid_t)-1;
        char *arg_pkgtype = NULL;
        const char *pkgtype;
-       char *pkgpath = NULL;
+       const char *pkgpath = NULL;
        char *args = NULL;
        char *reqkey = NULL;
        gchar **tmp_args = NULL;
@@ -380,6 +408,7 @@ static int __handle_request_mount_install(uid_t caller_uid,
        GVariant *value;
        int i = 0;
        int len = 0;
+       size_t s = 0;
 
        g_variant_get(parameters, "(u&s&s@as)", &target_uid, &arg_pkgtype,
                        &pkgpath, &value);
@@ -398,9 +427,12 @@ static int __handle_request_mount_install(uid_t caller_uid,
        }
 
        for (i = 0; i < args_count; i++) {
-               strncat(args, tmp_args[i], strlen(tmp_args[i]));
-               if (i != args_count - 1)
-                       strncat(args, " ", strlen(" "));
+               strncat(args, tmp_args[i], len - s - 1);
+               s += strlen(tmp_args[i]);
+               if (i != args_count - 1) {
+                       strncat(args, " ", len - s - 1);
+                       s += strlen(" ");
+               }
        }
 
        if (target_uid == (uid_t)-1 || pkgpath == NULL) {
@@ -410,6 +442,7 @@ static int __handle_request_mount_install(uid_t caller_uid,
                goto catch;
        }
 
+       pkgpath = _get_adjusted_pkgpath(pkgpath, caller_uid);
        pkgtype = _get_pkgtype_from_file(pkgpath);
        if (!pkgtype && arg_pkgtype && strlen(arg_pkgtype))
                pkgtype = (const char *)arg_pkgtype;
@@ -472,7 +505,7 @@ static int __handle_request_reinstall(uid_t caller_uid,
        pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
        if (pkgtype == NULL) {
                g_dbus_method_invocation_return_value(invocation,
-                               g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
+                               g_variant_new("(is)", PKGMGR_R_ENOPKG, ""));
                return -1;
        }
 
@@ -518,7 +551,7 @@ static int __handle_request_uninstall(uid_t caller_uid,
        pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
        if (pkgtype == NULL) {
                g_dbus_method_invocation_return_value(invocation,
-                               g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
+                               g_variant_new("(is)", PKGMGR_R_ENOPKG, ""));
                return -1;
        }
 
@@ -566,7 +599,7 @@ static int __handle_request_move(uid_t caller_uid,
        pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
        if (pkgtype == NULL) {
                g_dbus_method_invocation_return_value(invocation,
-                               g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
+                               g_variant_new("(is)", PKGMGR_R_ENOPKG, ""));
                return -1;
        }
 
@@ -624,7 +657,7 @@ static int __handle_request_enable_pkgs(uid_t caller_uid,
                if (pkgtype == NULL) {
                        g_dbus_method_invocation_return_value(invocation,
                                        g_variant_new("(is)",
-                                               PKGMGR_R_ESYSTEM, ""));
+                                               PKGMGR_R_ENOPKG, ""));
                        free(reqkey);
                        return -1;
                }
@@ -676,7 +709,7 @@ static int __handle_request_disable_pkgs(uid_t caller_uid,
                if (pkgtype == NULL) {
                        g_dbus_method_invocation_return_value(invocation,
                                        g_variant_new("(is)",
-                                               PKGMGR_R_ESYSTEM, ""));
+                                               PKGMGR_R_ENOPKG, ""));
                        free(reqkey);
                        return -1;
                }
@@ -700,6 +733,91 @@ static int __handle_request_disable_pkgs(uid_t caller_uid,
        return 0;
 }
 
+static int __handle_request_enable_apps(uid_t caller_uid,
+               GDBusMethodInvocation *invocation, GVariant *parameters)
+{
+       uid_t target_uid = (uid_t)-1;
+       char *appid;
+       char *reqkey;
+       char buf[MAX_PKG_ARGS_LEN];
+       GVariantIter *iter;
+
+       g_variant_get(parameters, "(uas)", &target_uid, &iter);
+       if (target_uid == (uid_t)-1 || iter == NULL) {
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
+               return -1;
+       }
+
+       reqkey = __generate_reqkey("enable_apps");
+       if (reqkey == NULL) {
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
+               return -1;
+       }
+
+       while (g_variant_iter_next(iter, "&s", &appid)) {
+               if (_push_queue(target_uid, caller_uid, reqkey,
+                                       REQUEST_TYPE_ENABLE_APP,
+                                       "default", appid, buf)) {
+                       g_dbus_method_invocation_return_value(invocation,
+                                       g_variant_new("(is)",
+                                               PKGMGR_R_ESYSTEM, ""));
+                       free(reqkey);
+                       return -1;
+               }
+       }
+
+       g_dbus_method_invocation_return_value(invocation,
+               g_variant_new("(is)", PKGMGR_R_OK, reqkey));
+
+       free(reqkey);
+       return 0;
+}
+
+static int __handle_request_disable_apps(uid_t caller_uid,
+               GDBusMethodInvocation *invocation, GVariant *parameters)
+{
+       uid_t target_uid = (uid_t)-1;
+       char *appid;
+       char *reqkey;
+       char buf[MAX_PKG_ARGS_LEN];
+       GVariantIter *iter;
+
+       g_variant_get(parameters, "(uas)", &target_uid, &iter);
+       if (target_uid == (uid_t)-1 || iter == NULL) {
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
+               return -1;
+       }
+
+       reqkey = __generate_reqkey("disable_apps");
+       if (reqkey == NULL) {
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
+               return -1;
+       }
+
+       while (g_variant_iter_next(iter, "&s", &appid)) {
+               if (_push_queue(target_uid, caller_uid, reqkey,
+                                       REQUEST_TYPE_DISABLE_APP,
+                                       "default", appid, buf)) {
+                       g_dbus_method_invocation_return_value(invocation,
+                                       g_variant_new("(is)",
+                                               PKGMGR_R_ESYSTEM, ""));
+                       free(reqkey);
+                       return -1;
+               }
+       }
+
+       g_dbus_method_invocation_return_value(invocation,
+               g_variant_new("(is)", PKGMGR_R_OK, reqkey));
+
+       free(reqkey);
+       return 0;
+
+}
+
 static int __handle_request_enable_app(uid_t caller_uid,
                GDBusMethodInvocation *invocation, GVariant *parameters)
 {
@@ -915,51 +1033,68 @@ static int __handle_request_getsize(uid_t caller_uid,
        return 0;
 }
 
-static int __handle_request_cleardata(uid_t caller_uid,
+static int __handle_request_getsize_sync(uid_t caller_uid,
                GDBusMethodInvocation *invocation, GVariant *parameters)
 {
        uid_t target_uid = (uid_t)-1;
-       char *pkgtype;
        char *pkgid = NULL;
-       char *reqkey = NULL;
+       int get_type = -1;
+       char *reqkey;
+       char buf[4];
 
-       g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
-       if (target_uid == (uid_t)-1 || pkgid == NULL) {
+       g_variant_get(parameters, "(u&si)", &target_uid, &pkgid, &get_type);
+       if (target_uid == (uid_t)-1 || pkgid == NULL || get_type == -1) {
                g_dbus_method_invocation_return_value(invocation,
-                               g_variant_new("(i)", PKGMGR_R_ECOMM));
+                               g_variant_new("(is)", PKGMGR_R_ECOMM, ""));
                return -1;
        }
 
-       pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
-       if (pkgtype == NULL) {
+       reqkey = __generate_reqkey(pkgid);
+       if (reqkey == NULL) {
                g_dbus_method_invocation_return_value(invocation,
-                               g_variant_new("(i)", PKGMGR_R_ESYSTEM));
+                               g_variant_new("(is)", PKGMGR_R_ENOMEM, ""));
                return -1;
        }
 
-       reqkey = __generate_reqkey(pkgid);
-       if (reqkey == NULL) {
+       snprintf(buf, sizeof(buf), "%d", get_type);
+       if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_GETSIZE_SYNC,
+                               "pkgtool", pkgid, buf)) {
                g_dbus_method_invocation_return_value(invocation,
-                               g_variant_new("(i)", PKGMGR_R_ENOMEM));
-               free(pkgtype);
+                               g_variant_new("(is)", PKGMGR_R_ESYSTEM, ""));
+               free(reqkey);
                return -1;
        }
 
-       if (_push_queue(target_uid, caller_uid, reqkey, REQUEST_TYPE_CLEARDATA,
-                               pkgtype, pkgid, NULL)) {
+       if (!g_hash_table_insert(req_table, (gpointer)reqkey,
+                               (gpointer)invocation))
+               ERR("reqkey already exists");
+
+       return 0;
+}
+
+static int __handle_request_cleardata(uid_t caller_uid,
+               GDBusMethodInvocation *invocation, GVariant *parameters)
+{
+       uid_t target_uid = (uid_t)-1;
+       char *pkgid = NULL;
+
+       g_variant_get(parameters, "(u&s)", &target_uid, &pkgid);
+       if (target_uid == (uid_t)-1 || pkgid == NULL) {
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(i)", PKGMGR_R_ECOMM));
+               return -1;
+       }
+
+       if (_push_queue(target_uid, caller_uid, NULL, REQUEST_TYPE_CLEARDATA,
+                               "pkgtool", pkgid, NULL)) {
                g_dbus_method_invocation_return_value(invocation,
                                g_variant_new("(i)", PKGMGR_R_ESYSTEM));
-               free(reqkey);
-               free(pkgtype);
                return -1;
        }
 
        g_dbus_method_invocation_return_value(invocation,
                        g_variant_new("(i)", PKGMGR_R_OK));
 
-       free(reqkey);
-       free(pkgtype);
-
        return 0;
 }
 
@@ -1385,6 +1520,55 @@ static int __handle_request_set_app_label(uid_t uid,
        return 0;
 }
 
+static int __handle_request_migrate_external_image(uid_t uid,
+               GDBusMethodInvocation *invocation, GVariant *parameters)
+{
+       uid_t target_uid = (uid_t)-1;
+       char *pkgid = NULL;
+       char *pkgtype;
+       char *reqkey;
+
+       g_variant_get(parameters, "(us)", &target_uid, &pkgid);
+       if (target_uid == (uid_t)-1 || pkgid == NULL) {
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(i)", PKGMGR_R_ECOMM));
+               return -1;
+       }
+
+       pkgtype = _get_pkgtype_from_pkgid(pkgid, target_uid);
+       if (pkgtype == NULL) {
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(i)", PKGMGR_R_ENOPKG));
+               return -1;
+       }
+
+       reqkey = __generate_reqkey(pkgid);
+       if (reqkey == NULL) {
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(i)", PKGMGR_R_ENOMEM));
+               free(pkgtype);
+               return -1;
+       }
+
+       if (_push_queue(target_uid, uid, reqkey,
+                               REQUEST_TYPE_MIGRATE_EXTERNAL_IMAGE,
+                               pkgtype, pkgid, NULL)) {
+               g_dbus_method_invocation_return_value(invocation,
+                               g_variant_new("(i)", PKGMGR_R_ESYSTEM));
+               free(reqkey);
+               free(pkgtype);
+               return -1;
+       }
+
+       g_dbus_method_invocation_return_value(invocation,
+                       g_variant_new("(i)", PKGMGR_R_OK));
+
+       free(reqkey);
+       free(pkgtype);
+
+       return 0;
+}
+
 static uid_t __get_caller_uid(GDBusConnection *connection, const char *name)
 {
        GError *err = NULL;
@@ -1403,6 +1587,7 @@ static uid_t __get_caller_uid(GDBusConnection *connection, const char *name)
        }
 
        g_variant_get(result, "(u)", &uid);
+       g_variant_unref(result);
 
        return uid;
 }
@@ -1443,12 +1628,18 @@ static void __handle_method_call(GDBusConnection *connection,
                ret = __handle_request_disable_pkgs(uid, invocation, parameters);
        else if (g_strcmp0(method_name, "getsize") == 0)
                ret = __handle_request_getsize(uid, invocation, parameters);
+       else if (g_strcmp0(method_name, "getsize_sync") == 0)
+               ret = __handle_request_getsize_sync(uid, invocation, parameters);
        else if (g_strcmp0(method_name, "clearcache") == 0)
                ret = __handle_request_clearcache(uid, invocation, parameters);
        else if (g_strcmp0(method_name, "enable_app") == 0)
                ret = __handle_request_enable_app(uid, invocation, parameters);
        else if (g_strcmp0(method_name, "disable_app") == 0)
                ret = __handle_request_disable_app(uid, invocation, parameters);
+       else if (g_strcmp0(method_name, "enable_apps") == 0)
+               ret = __handle_request_enable_apps(uid, invocation, parameters);
+       else if (g_strcmp0(method_name, "disable_apps") == 0)
+               ret = __handle_request_disable_apps(uid, invocation, parameters);
        else if (g_strcmp0(method_name, "enable_global_app_for_uid") == 0)
                ret = __handle_request_enable_global_app_for_uid(uid,
                                invocation, parameters);
@@ -1485,6 +1676,9 @@ static void __handle_method_call(GDBusConnection *connection,
                                parameters);
        else if (g_strcmp0(method_name, "set_app_label") == 0)
                ret = __handle_request_set_app_label(uid, invocation, parameters);
+       else if (g_strcmp0(method_name, "migrate_external_image") == 0)
+               ret = __handle_request_migrate_external_image(uid, invocation,
+                               parameters);
        else
                ret = -1;