Buffer not null terminated
[framework/web/wrt-installer.git] / src / pkg-manager / backendlib.cpp
index 1861b94..60eb9b0 100644 (file)
@@ -23,6 +23,8 @@
  *             to package manager
  */
 #include "package-manager-plugin.h"
+#include <package-manager.h>
+#include <regex.h>
 #include <dlog.h>
 #include <dpl/wrt-dao-ro/global_config.h>
 #include <vcore/VCore.h>
 #include <dpl/foreach.h>
 #include <dpl/utils/folder_size.h>
 #include <dpl/wrt-dao-ro/wrt_db_types.h>
+#include <dpl/copy.h>
+#include <dpl/abstract_waitable_input_adapter.h>
+#include <dpl/abstract_waitable_output_adapter.h>
+#include <dpl/zip_input.h>
+#include <dpl/binary_queue.h>
+#include <dpl/file_input.h>
+#include <dpl/wrt-dao-ro/config_parser_data.h>
+#include "root_parser.h"
+#include "widget_parser.h"
+#include "parser_runner.h"
 
 using namespace WrtDB;
 
@@ -43,7 +55,7 @@ using namespace WrtDB;
 #undef FALSE
 #define TRUE 0
 #define FALSE -1
-#define GET_DIRECTORY_SIZE_KB(x)    (x)/1024
+#define GET_DIRECTORY_SIZE_KB(x)    (x) / 1024
 
 #ifdef __cplusplus
 extern "C"
@@ -53,11 +65,19 @@ extern "C"
 static void pkg_native_plugin_on_unload();
 static int pkg_plugin_app_is_installed(const char *pkg_name);
 static int pkg_plugin_get_installed_apps_list(const char *category,
-        const char *option, package_manager_pkg_info_t **list, int *count);
-static int pkg_plugin_get_app_detail_info(const char *pkg_name,
-        package_manager_pkg_detail_info_t *pkg_detail_info);
-static int pkg_plugin_get_app_detail_info_from_package(const char *pkg_path,
-        package_manager_pkg_detail_info_t *pkg_detail_info);
+                                              const char *option,
+                                              package_manager_pkg_info_t **list,
+                                              int *count);
+static int pkg_plugin_get_app_detail_info(
+    const char *pkg_name,
+    package_manager_pkg_detail_info_t *
+    pkg_detail_info);
+static int pkg_plugin_get_app_detail_info_from_package(
+    const char *pkg_path,
+    package_manager_pkg_detail_info_t
+    *pkg_detail_info);
+
+pkgmgr_info *pkgmgr_client_check_pkginfo_from_file(const char *pkg_path);
 
 static void pkg_native_plugin_on_unload()
 {
@@ -66,12 +86,28 @@ static void pkg_native_plugin_on_unload()
 
 static int pkg_plugin_app_is_installed(const char *pkg_name)
 {
+    const char* REG_PKGID_PATTERN = "^[a-zA-Z0-9]{10}$";
     LogDebug("pkg_plugin_app_is_installed() is called");
 
     WrtDB::WrtDatabase::attachToThreadRO();
 
-    bool result = WidgetDAOReadOnly::isWidgetInstalled(
-                    DPL::FromUTF8String(pkg_name));
+    regex_t reg;
+    if (regcomp(&reg, REG_PKGID_PATTERN, REG_NOSUB | REG_EXTENDED) != 0) {
+        LogDebug("Regcomp failed");
+    }
+
+    WrtDB::TizenAppId appid;
+
+    if ((regexec(&reg, pkg_name,
+                    static_cast<size_t>(0), NULL, 0) == 0))
+    {
+        WrtDB::TizenPkgId pkgid(DPL::FromUTF8String(pkg_name));
+        appid = WidgetDAOReadOnly::getTzAppId(pkgid);
+    } else {
+        appid = DPL::FromUTF8String(pkg_name);
+    }
+
+    bool result = WidgetDAOReadOnly::isWidgetInstalled(appid);
     WrtDB::WrtDatabase::detachFromThread();
 
     if (result) {
@@ -82,19 +118,20 @@ static int pkg_plugin_app_is_installed(const char *pkg_name)
 }
 
 static int pkg_plugin_get_installed_apps_list(const char * /*category*/,
-        const char * /*option*/, package_manager_pkg_info_t **list, int *count)
+                                              const char * /*option*/,
+                                              package_manager_pkg_info_t **list,
+                                              int *count)
 {
     LogDebug("pkg_plugin_get_installed_apps_list() is called");
 
     package_manager_pkg_info_t *pkg_list = NULL;
     package_manager_pkg_info_t *pkg_last = NULL;
 
-
     WrtDB::WrtDatabase::attachToThreadRO();
-    WidgetPkgNameList_NOTNULL pkgnameslList = WidgetDAOReadOnly::getPkgnameList_NOTNULL();
+    TizenAppIdList tizenAppidList = WidgetDAOReadOnly::getTizenAppidList();
     *count = 0;
 
-    FOREACH(iterator, pkgnameslList) {
+    FOREACH(iterator, tizenAppidList) {
         package_manager_pkg_info_t *pkg_info =
             static_cast<package_manager_pkg_info_t*>
             (malloc(sizeof(package_manager_pkg_info_t)));
@@ -106,11 +143,11 @@ static int pkg_plugin_get_installed_apps_list(const char * /*category*/,
             pkg_last->next = pkg_info;
         }
 
-        WidgetPkgName pkgname = *iterator;
-        WidgetDAOReadOnly widget(pkgname);
+        TizenAppId tzAppid = *iterator;
+        WidgetDAOReadOnly widget(tzAppid);
         strncpy(pkg_info->pkg_type, "wgt", PKG_TYPE_STRING_LEN_MAX);
         snprintf(pkg_info->pkg_name, PKG_NAME_STRING_LEN_MAX, "%s",
-                DPL::ToUTF8String(pkgname).c_str());
+                 DPL::ToUTF8String(tzAppid).c_str());
 
         DPL::Optional<DPL::String> version = widget.getVersion();
         if (!version.IsNull()) {
@@ -128,15 +165,16 @@ static int pkg_plugin_get_installed_apps_list(const char * /*category*/,
     return TRUE;
 }
 
-static int pkg_plugin_get_app_detail_info(const char *pkg_name,
-        package_manager_pkg_detail_info_t *pkg_detail_info)
+static int pkg_plugin_get_app_detail_info(
+    const char *pkg_name,
+    package_manager_pkg_detail_info_t *
+    pkg_detail_info)
 {
     LogDebug("pkg_plugin_get_app_detail_info() is called");
 
-
     WrtDB::WrtDatabase::attachToThreadRO();
     int handle = WidgetDAOReadOnly::getHandle(
-                    DPL::FromUTF8String(pkg_name));
+            DPL::FromUTF8String(pkg_name));
     WidgetDAOReadOnly widget(handle);
 
     DPL::Optional<DPL::String> version = widget.getVersion();
@@ -149,7 +187,7 @@ static int pkg_plugin_get_app_detail_info(const char *pkg_name,
                 PKG_VERSION_STRING_LEN_MAX - 1);
     }
     snprintf(pkg_detail_info->optional_id, PKG_NAME_STRING_LEN_MAX, "%d",
-           handle);
+             handle);
     WidgetLocalizedInfo localizedInfo;
 
     if (locale.IsNull()) {
@@ -196,13 +234,212 @@ static int pkg_plugin_get_app_detail_info(const char *pkg_name,
     return TRUE;
 }
 
+int getConfigParserData(const std::string &widgetPath, ConfigParserData& configInfo)
+{
+    const char* CONFIG_XML = "config.xml";
+    const char* WITH_OSP_XML = "res/wgt/config.xml";
+
+    Try {
+        ParserRunner parser;
+
+        std::unique_ptr<DPL::ZipInput> zipFile(
+                new DPL::ZipInput(widgetPath));
+
+        std::unique_ptr<DPL::ZipInput::File> configFile;
+
+        // Open config.xml file
+        Try {
+            configFile.reset(zipFile->OpenFile(CONFIG_XML));
+        }
+        Catch(DPL::ZipInput::Exception::OpenFileFailed)
+        {
+            configFile.reset(zipFile->OpenFile(WITH_OSP_XML));
+        }
+
+        // Extract config
+        DPL::BinaryQueue buffer;
+        DPL::AbstractWaitableInputAdapter inputAdapter(configFile.get());
+        DPL::AbstractWaitableOutputAdapter outputAdapter(&buffer);
+        DPL::Copy(&inputAdapter, &outputAdapter);
+        parser.Parse(&buffer,
+                ElementParserPtr(
+                    new RootParser<WidgetParser>(configInfo,
+                        DPL::
+                        FromUTF32String(
+                            L"widget"))));
+    }
+    Catch(DPL::ZipInput::Exception::OpenFailed)
+    {
+        LogError("Failed to open widget package");
+        return FALSE;
+    }
+    Catch(DPL::ZipInput::Exception::OpenFileFailed)
+    {
+        LogError("Failed to open config.xml file");
+        return FALSE;
+    }
+    Catch(DPL::CopyFailed)
+    {
+        LogError("Failed to extract config.xml file");
+        return FALSE;
+    }
+    Catch(DPL::FileInput::Exception::OpenFailed)
+    {
+        LogError("Failed to open config.xml file");
+        return FALSE;
+    }
+    Catch(ElementParser::Exception::ParseError)
+    {
+        LogError("Failed to parse config.xml file");
+        return FALSE;
+    }
+    Catch(DPL::ZipInput::Exception::SeekFileFailed)
+    {
+        LogError("Failed to seek widget archive - corrupted package?");
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
+char* getIconInfo(const std::string widgetPath,
+        const std::string icon_name, int &icon_size)
+{
+    Try {
+        std::unique_ptr<DPL::ZipInput> zipFile(
+                new DPL::ZipInput(widgetPath));
+
+        std::unique_ptr<DPL::ZipInput::File> iconFile;
+
+        iconFile.reset(zipFile->OpenFile(icon_name));
+
+        DPL::BinaryQueue buffer;
+        DPL::AbstractWaitableInputAdapter inputAdapter(iconFile.get());
+        DPL::AbstractWaitableOutputAdapter outputAdapter(&buffer);
+        DPL::Copy(&inputAdapter, &outputAdapter);
+        icon_size = buffer.Size();
+        char *getBuffer = (char*) calloc(1, (sizeof(char) * icon_size) + 1);
+        buffer.Flatten(getBuffer, buffer.Size());
+        return getBuffer;
+    }
+    Catch(DPL::ZipInput::Exception::OpenFailed)
+    {
+        LogError("Failed to open widget package");
+        return NULL;
+    }
+    Catch(DPL::ZipInput::Exception::OpenFileFailed)
+    {
+        LogError("Failed to open icon file");
+        return NULL;
+    }
+}
+
+int getWidgetDetailInfoFromPackage(const char* pkgPath,
+        package_manager_pkg_detail_info_t* pkg_detail_info)
+{
+    const std::string widget_path(pkgPath);
+    ConfigParserData configInfo;
+
+    if (FALSE == getConfigParserData(widget_path, configInfo)) {
+        return FALSE;
+    }
+
+    strncpy(pkg_detail_info->pkg_type, "wgt", PKG_TYPE_STRING_LEN_MAX);
+    if (!configInfo.tizenPkgId.IsNull()) {
+        strncpy(pkg_detail_info->pkgid,
+                DPL::ToUTF8String(*configInfo.tizenPkgId).c_str(), PKG_TYPE_STRING_LEN_MAX - 1);
+    }
+    if (!configInfo.version.IsNull()) {
+        strncpy(pkg_detail_info->version,
+                DPL::ToUTF8String(*configInfo.version).c_str(),
+                PKG_VERSION_STRING_LEN_MAX - 1);
+    }
+
+    DPL::Optional<DPL::String> name;
+    DPL::Optional<DPL::String> desc;
+    DPL::OptionalString defaultLocale = configInfo.defaultlocale;
+
+    FOREACH(localizedData, configInfo.localizedDataSet)
+    {
+        Locale i = localizedData->first;
+        if (!!defaultLocale) {
+            if (defaultLocale == i) {
+                name = localizedData->second.name;
+                desc = localizedData->second.description;
+                break;
+            }
+        } else {
+            name = localizedData->second.name;
+            desc = localizedData->second.description;
+            break;
+        }
+    }
+
+    if( !name.IsNull()) {
+        strncpy(pkg_detail_info->pkg_name, DPL::ToUTF8String(*name).c_str(), PKG_NAME_STRING_LEN_MAX - 1);
+    }
+
+    if (!desc.IsNull()) {
+        strncpy(pkg_detail_info->pkg_description,
+                DPL::ToUTF8String(*desc).c_str(),
+                PKG_VALUE_STRING_LEN_MAX - 1);
+    }
+
+    if (!configInfo.tizenMinVersionRequired.IsNull()) {
+        strncpy(pkg_detail_info->min_platform_version,
+                DPL::ToUTF8String(*configInfo.tizenMinVersionRequired).c_str(),
+                PKG_VERSION_STRING_LEN_MAX);
+    }
+
+    if (!configInfo.authorName.IsNull()) {
+        strncpy(pkg_detail_info->author,
+                DPL::ToUTF8String(*configInfo.authorName).c_str(),
+                PKG_VALUE_STRING_LEN_MAX - 1);
+    }
+
+    std::string icon_name;
+
+    FOREACH(i, configInfo.iconsList) {
+        LogDebug("icon name: " << i->src);
+        icon_name = DPL::ToUTF8String(i->src);
+        break;
+    }
+    pkg_detail_info->icon_buf = getIconInfo(widget_path, icon_name,
+            pkg_detail_info->icon_size);
+    LogDebug("icon size : " << pkg_detail_info->icon_size);
+
+    GList *privilege_list = NULL;
+    FOREACH(it, configInfo.featuresList) {
+        LogDebug("privilege : " << it->name);
+        int length = DPL::ToUTF8String(it->name).length();
+        char *privilege = (char*) calloc(1, (sizeof(char) * length) + 1);
+        snprintf(privilege, length + 1, "%s",
+                DPL::ToUTF8String(it->name).c_str());
+        privilege_list = g_list_append(privilege_list, privilege);
+    }
+    pkg_detail_info->privilege_list = privilege_list;
+
+    return TRUE;
+}
+
 static int pkg_plugin_get_app_detail_info_from_package(
-        const char * /*pkg_path*/,
-        package_manager_pkg_detail_info_t * /*pkg_detail_info*/)
+    const char * pkg_path,
+    package_manager_pkg_detail_info_t * pkg_detail_info)
 {
     LogDebug("pkg_plugin_get_app_detail_info_from_package() is called");
+    return getWidgetDetailInfoFromPackage(pkg_path, pkg_detail_info);
+}
 
-    return TRUE;
+pkgmgr_info *pkgmgr_client_check_pkginfo_from_file(const char *pkg_path)
+{
+    LogDebug("pkgmgr_client_check_pkginfo_from_file() is called");
+    package_manager_pkg_detail_info_t pkg_detail_info;
+    int ret = getWidgetDetailInfoFromPackage(pkg_path, &pkg_detail_info);
+    if (FALSE == ret) {
+        LogError("Failed to get package detail info ");
+        return NULL;
+    }
+    return &pkg_detail_info;
 }
 
 __attribute__ ((visibility("default")))