#include <glib.h>
#include <getopt.h>
+#include <pkgmgr-info.h>
#include <tzplatform_config.h>
#include "package-manager.h"
typedef struct pkgfile_info {
char *path;
+ char *pkgid;
+ char *version;
char *backend_type;
install_type install_type;
bool skip_check_reference;
GList *pkgfile_info_list;
GList *rw_pkgfile_info_list;
+GList *duplicated_rw_pkgfile_info_list;
static void __free_pkgfile_info_list(gpointer data)
{
pkgfile_info *info = (pkgfile_info *)data;
free(info->path);
+ free(info->pkgid);
+ free(info->version);
free(info->backend_type);
free(info);
}
pkgfile_info *pkgfile;
int ret = 0;
FILE *fp;
+ package_manager_pkg_detail_info_t *pkg_info;
if (directory == NULL || type == INSTALL_TYPE_UNDEFINED)
return -1;
pkgfile->pkg_size = ftell(fp);
fclose(fp);
+ pkg_info = pkgmgr_client_check_pkginfo_from_file(pkgfile->path);
+ if (pkg_info == NULL) {
+ _E("can not get pkg_info from [%s]\n", pkgfile->path);
+ continue;
+ }
+
+ pkgfile->pkgid = strdup(pkg_info->pkgid);
+ if (pkgfile->pkgid == NULL) {
+ _E("Out of memory\n");
+ pkgmgr_client_free_pkginfo(pkg_info);
+ __free_pkgfile_info_list((gpointer)pkgfile);
+ closedir(dir);
+ return -1;
+ }
+
+ pkgfile->version = strdup(pkg_info->version);
+ if (pkgfile->version == NULL) {
+ _E("Out of memory\n");
+ pkgmgr_client_free_pkginfo(pkg_info);
+ __free_pkgfile_info_list((gpointer)pkgfile);
+ closedir(dir);
+ return -1;
+ }
+
+ pkgmgr_client_free_pkginfo(pkg_info);
+
*list = g_list_prepend(*list, pkgfile);
}
return 0;
}
+static gint __compare_pkgid(gconstpointer data1, gconstpointer data2)
+{
+ struct pkgfile_info *info1 = (struct pkgfile_info *)data1;
+ struct pkgfile_info *info2 = (struct pkgfile_info *)data2;
+ return strcmp(info1->pkgid, info2->pkgid);
+}
+
+static int __should_install_rw_pkg(struct pkgfile_info *rw, pkgfile_info *ro)
+{
+ int ret;
+ pkgmgrinfo_version_compare_type result;
+
+ ret = pkgmgrinfo_compare_package_version(rw->version, ro->version,
+ &result);
+ if (ret != PMINFO_R_OK) {
+ _E("Failed to compare package version [%s] and [%s]\n",
+ rw->path, ro->path);
+ return -1;
+ }
+
+ if (result == PMINFO_VERSION_SAME)
+ return 0;
+ /* ro->version is higher than rw->version */
+ else if (result == PMINFO_VERSION_NEW)
+ return 0;
+ else
+ return 1;
+}
+
+static void _find_duplicated_rw_pkgfile_info(void)
+{
+ GList *iter = rw_pkgfile_info_list;
+ GList *next;
+ GList *ro_iter;
+
+ while (iter != NULL) {
+ next = iter->next;
+ ro_iter = g_list_find_custom(pkgfile_info_list, iter->data,
+ __compare_pkgid);
+ /* found same pkgid in preload tpk(RO) */
+ if (ro_iter != NULL) {
+ rw_pkgfile_info_list = g_list_remove_link(
+ rw_pkgfile_info_list, iter);
+ if (__should_install_rw_pkg(iter->data, ro_iter->data))
+ duplicated_rw_pkgfile_info_list = g_list_concat(
+ duplicated_rw_pkgfile_info_list,
+ iter);
+ else
+ g_list_free_full(iter, __free_pkginfo);
+ }
+ iter = next;
+ }
+}
+
static void _sort_pkgfile_info_list() {
pkgfile_info_list = g_list_sort(pkgfile_info_list, __pkgfileinfo_compare);
rw_pkgfile_info_list = g_list_sort(rw_pkgfile_info_list, __pkgfileinfo_compare);
+ _find_duplicated_rw_pkgfile_info();
pkgfile_info_list = g_list_concat(rw_pkgfile_info_list, pkgfile_info_list);
rw_pkgfile_info_list = NULL;
+ pkgfile_info_list = g_list_concat(pkgfile_info_list, duplicated_rw_pkgfile_info_list);
+ duplicated_rw_pkgfile_info_list = NULL;
}
static int _install_pkg_with_pkginfo()
goto error;
/* sort pkgfile_info_list and rw_pkgfile_info_list first,
- * and concat rw_pkgfile_info_list to pkgfile_info_list
+ * and concat rw_pkgfile_info_list to pkgfile_info_list.
+ * if there are pkgs that has same pkgid and higer version
+ * in both list, rw one will be installed later.
*/
_sort_pkgfile_info_list();