summaryrefslogtreecommitdiffstats
path: root/src/software-dbus/sw-utils.c
diff options
context:
space:
mode:
authorPeter Schiffer <pschiffe@redhat.com>2014-05-05 17:21:26 +0200
committerPeter Schiffer <pschiffe@redhat.com>2014-05-07 11:49:43 +0200
commit77185c85eeaf915e8b3892ed8f89307545b492a9 (patch)
treeac74724bb8e751f62d7c377e577f9df1a7365f35 /src/software-dbus/sw-utils.c
parent7b692ec1616c4c83e89d1be09476be9d7634394c (diff)
downloadopenlmi-providers-77185c85eeaf915e8b3892ed8f89307545b492a9.tar.gz
openlmi-providers-77185c85eeaf915e8b3892ed8f89307545b492a9.tar.xz
openlmi-providers-77185c85eeaf915e8b3892ed8f89307545b492a9.zip
Software-dbus: implemented LMI_ResourceForSoftwareIdentityProvider
Diffstat (limited to 'src/software-dbus/sw-utils.c')
-rw-r--r--src/software-dbus/sw-utils.c476
1 files changed, 368 insertions, 108 deletions
diff --git a/src/software-dbus/sw-utils.c b/src/software-dbus/sw-utils.c
index 76ca58b..e523fd2 100644
--- a/src/software-dbus/sw-utils.c
+++ b/src/software-dbus/sw-utils.c
@@ -49,27 +49,36 @@ void free_sw_package(SwPackage *pkg)
init_sw_package(pkg);
}
-short create_sw_package_from_pk_pkg(PkPackage *pk_pkg, SwPackage *sw_pkg)
+short create_sw_package_from_pk_pkg_id(const char *pk_pkg_id, SwPackage *sw_pkg)
{
short ret = -1;
char *delim;
- const char *id, *name, *arch, *ver;
+ const gchar *id, *name, *arch, *ver;
+ gchar **split_id = NULL;
init_sw_package(sw_pkg);
- if (!(id = pk_package_get_id(pk_pkg))) {
- warn("Package without ID!");
+ if (!pk_pkg_id || !*pk_pkg_id) {
+ warn("Empty package ID!");
+ goto done;
+ }
+
+ id = pk_pkg_id;
+ split_id = pk_package_id_split(id);
+ if (!split_id) {
+ warn("Invalid package ID: %s!", id);
goto done;
}
- if (!(name = pk_package_get_name(pk_pkg))) {
+
+ if (!(name = split_id[PK_PACKAGE_ID_NAME])) {
warn("Package with ID: %s doesn't have name!", id);
goto done;
}
- if (!(ver = pk_package_get_version(pk_pkg))) {
+ if (!(ver = split_id[PK_PACKAGE_ID_VERSION])) {
warn("Package with ID: %s doesn't have version!", id);
goto done;
}
- if (!(arch = pk_package_get_arch(pk_pkg))) {
+ if (!(arch = split_id[PK_PACKAGE_ID_ARCH])) {
warn("Package with ID: %s doesn't have architecture!", id);
goto done;
}
@@ -110,6 +119,11 @@ done:
return ret;
}
+short create_sw_package_from_pk_pkg(PkPackage *pk_pkg, SwPackage *sw_pkg)
+{
+ return create_sw_package_from_pk_pkg_id(pk_package_get_id(pk_pkg), sw_pkg);
+}
+
short create_sw_package_from_elem_name(const char *elem_name, SwPackage *sw_pkg)
{
short ret = -1;
@@ -266,30 +280,21 @@ done:
return;
}
-void get_pk_det_from_pk_pkg(PkPackage *pk_pkg, PkDetails **pk_det)
+void get_pk_det_from_pk_pkg(PkPackage *pk_pkg, PkDetails **pk_det, PkTask *task_p)
{
- PkTask *task = NULL;
PkDetails *item = NULL;
- PkResults *results = NULL;
GPtrArray *array = NULL;
- GError *gerror = NULL;
gchar **values = NULL;
unsigned i;
- char error_msg[ERROR_MSG_LEN] = "";
-
- task = pk_task_new();
values = g_new0(gchar*, 2);
values[0] = g_strdup(pk_package_get_id(pk_pkg));
- results = pk_task_get_details_sync(task, values, NULL, NULL, NULL, &gerror);
- if (check_and_create_error_msg(results, gerror,
- "Getting package details failed", error_msg, ERROR_MSG_LEN)) {
- warn(error_msg);
+ get_pk_det_from_array(values, &array, task_p);
+ if (!array) {
goto done;
}
- array = pk_results_get_details_array(results);
for (i = 0; i < array->len; i++) {
item = g_ptr_array_index(array, i);
if (strcmp(pk_details_get_package_id(item),
@@ -301,17 +306,10 @@ void get_pk_det_from_pk_pkg(PkPackage *pk_pkg, PkDetails **pk_det)
done:
g_strfreev(values);
- g_clear_error(&gerror);
if (array) {
g_ptr_array_unref(array);
}
- if (results) {
- g_object_unref(results);
- }
- if (task) {
- g_object_unref(task);
- }
return;
}
@@ -403,39 +401,133 @@ done:
return;
}
-void enum_sw_identity_instance_names(PkBitfield filters, const CMPIBroker *cb,
- const char *ns, const CMPIResult* cr, char *error_msg,
- const unsigned error_msg_len)
+void get_pk_det_from_array(const char **values_p, GPtrArray **garray,
+ PkTask *task_p)
+{
+ PkTask *task = NULL;
+ PkResults *results = NULL;
+ GPtrArray *array = NULL, *array2 = NULL;
+ GError *gerror = NULL;
+ gchar **values = NULL;
+ unsigned i, j, values_p_count = 0;
+ char error_msg[ERROR_MSG_LEN] = "";
+
+ if (!values_p || !*values_p) {
+ warn("No package IDs given.");
+ goto done;
+ }
+
+ while (values_p[++values_p_count]);
+
+ if (task_p) {
+ task = task_p;
+ } else {
+ task = pk_task_new();
+ }
+
+ if (values_p_count < PK_DETAILS_LIMIT) {
+ values = g_new0(gchar*, values_p_count + 1);
+ } else {
+ values = g_new0(gchar*, PK_DETAILS_LIMIT + 1);
+ }
+
+ for (i = 0; i < values_p_count / PK_DETAILS_LIMIT + 1; i++) {
+ j = 0;
+ while (values[j]) {
+ values[j++] = NULL;
+ }
+
+ for (j = i * PK_DETAILS_LIMIT;
+ j < (i + 1) * PK_DETAILS_LIMIT && j < values_p_count; j++) {
+ values[j - i * PK_DETAILS_LIMIT] = values_p[j];
+ }
+
+ results = pk_task_get_details_sync(task, values, NULL, NULL, NULL, &gerror);
+ if (check_and_create_error_msg(results, gerror,
+ "Getting package details failed", error_msg, ERROR_MSG_LEN)) {
+ warn(error_msg);
+ goto done;
+ }
+
+ array = pk_results_get_details_array(results);
+ gc_gobject_ptr_array_append(&array2, array);
+
+ if (results) {
+ g_object_unref(results);
+ results = NULL;
+ }
+ if (array) {
+ g_ptr_array_unref(array);
+ array = NULL;
+ }
+ }
+
+ g_ptr_array_sort(array2, (GCompareFunc) pk_det_cmp);
+ *garray = g_ptr_array_ref(array2);
+
+done:
+ g_clear_error(&gerror);
+
+ if (values) {
+ g_free(values);
+ }
+ if (array) {
+ g_ptr_array_unref(array);
+ }
+ if (array2) {
+ g_ptr_array_unref(array2);
+ }
+ if (results) {
+ g_object_unref(results);
+ }
+ if (!task_p && task) {
+ g_object_unref(task);
+ }
+
+ return;
+}
+
+void k_return_sw_identity_op_from_pkg_id(const char *pkg_id,
+ const CMPIBroker *cb, const char *ns, const CMPIResult* cr)
{
- GPtrArray *array = NULL;
SwPackage sw_pkg;
- unsigned i;
char elem_name[ELEM_NAME_LEN] = "", instance_id[INSTANCE_ID_LEN] = "";
init_sw_package(&sw_pkg);
- get_pk_packages(filters, &array, error_msg, error_msg_len);
- if (!array) {
+ if (create_sw_package_from_pk_pkg_id(pkg_id, &sw_pkg) != 0) {
goto done;
}
- for (i = 0; i < array->len; i++) {
- if (create_sw_package_from_pk_pkg(g_ptr_array_index(array, i),
- &sw_pkg) != 0) {
- continue;
- }
+ sw_pkg_get_element_name(&sw_pkg, elem_name, ELEM_NAME_LEN);
- sw_pkg_get_element_name(&sw_pkg, elem_name, ELEM_NAME_LEN);
+ create_instance_id(SW_IDENTITY_CLASS_NAME, elem_name, instance_id,
+ INSTANCE_ID_LEN);
- create_instance_id(SW_IDENTITY_CLASS_NAME, elem_name, instance_id,
- INSTANCE_ID_LEN);
+ LMI_SoftwareIdentityRef w;
+ LMI_SoftwareIdentityRef_Init(&w, cb, ns);
+ LMI_SoftwareIdentityRef_Set_InstanceID(&w, instance_id);
+ KReturnObjectPath(cr, w);
- free_sw_package(&sw_pkg);
+done:
+ free_sw_package(&sw_pkg);
+}
+
+void enum_sw_identity_instance_names(PkBitfield filters, const CMPIBroker *cb,
+ const char *ns, const CMPIResult* cr, char *error_msg,
+ const unsigned error_msg_len)
+{
+ GPtrArray *array = NULL;
+ unsigned i;
+
+ get_pk_packages(filters, &array, error_msg, error_msg_len);
+ if (!array) {
+ goto done;
+ }
- LMI_SoftwareIdentityRef w;
- LMI_SoftwareIdentityRef_Init(&w, cb, ns);
- LMI_SoftwareIdentityRef_Set_InstanceID(&w, instance_id);
- KReturnObjectPath(cr, w);
+ for (i = 0; i < array->len; i++) {
+ k_return_sw_identity_op_from_pkg_id(
+ pk_package_get_id(g_ptr_array_index(array, i)), cb, ns, cr);
}
done:
@@ -451,99 +543,145 @@ void enum_sw_identity_instances(PkBitfield filters, const CMPIBroker *cb,
const unsigned error_msg_len)
{
LMI_SoftwareIdentity w;
- PkTask *task = NULL;
PkPackage *pk_pkg = NULL;
PkDetails *pk_det = NULL;
- PkResults *results = NULL;
- GPtrArray *array = NULL, *array2 = NULL;
- GError *gerror = NULL;
+ GPtrArray *pkg_array = NULL, *det_array = NULL;
gchar **values = NULL;
SwPackage sw_pkg;
int cmpres;
- unsigned i, j, a2i;
+ unsigned i, det_a_i = 0;
init_sw_package(&sw_pkg);
- get_pk_packages(filters, &array, error_msg, error_msg_len);
- if (!array) {
+ get_pk_packages(filters, &pkg_array, error_msg, error_msg_len);
+ if (!pkg_array) {
goto done;
}
- task = pk_task_new();
-
- for (i = 0; i < array->len / PK_DETAILS_LIMIT + 1; i++) {
- values = g_new0(gchar*, PK_DETAILS_LIMIT + 1);
+ values = g_new0(gchar*, pkg_array->len + 1);
+ for (i = 0; i < pkg_array->len; i++) {
+ values[i] = g_strdup(pk_package_get_id(g_ptr_array_index(pkg_array, i)));
+ }
+ get_pk_det_from_array(values, &det_array, NULL);
+ g_strfreev(values);
+ values = NULL;
- for (j = i * PK_DETAILS_LIMIT;
- j < (i + 1) * PK_DETAILS_LIMIT && j < array->len; j++) {
- values[j - i * PK_DETAILS_LIMIT] = g_strdup(pk_package_get_id(
- g_ptr_array_index(array, j)));
+ for (i = 0; i < pkg_array->len; i++) {
+ pk_pkg = g_ptr_array_index(pkg_array, i);
+ if (create_sw_package_from_pk_pkg(pk_pkg, &sw_pkg) != 0) {
+ continue;
}
- results = pk_task_get_details_sync(task, values, NULL, NULL, NULL, &gerror);
- if (check_and_create_error_msg(results, gerror,
- "Getting package details failed", error_msg, error_msg_len)) {
- warn(error_msg);
- /* This is non-fatal problem. */
- error_msg[0] = '\0';
- } else {
- array2 = pk_results_get_details_array(results);
- g_ptr_array_sort(array2, (GCompareFunc) pk_det_cmp);
+ cmpres = -1;
+ if (det_array) {
+ while (cmpres < 0 && det_a_i < det_array->len) {
+ pk_det = g_ptr_array_index(det_array, det_a_i);
+ cmpres = strcmp(pk_details_get_package_id(pk_det),
+ pk_package_get_id(pk_pkg));
+ if (cmpres < 0) {
+ /* this should not happen -
+ * we have spare unmatched package details */
+ det_a_i++;
+ } else if (cmpres > 0) {
+ /* no matching package details for current pk_pkg */
+ pk_det = NULL;
+ } else {
+ /* found a match */
+ det_a_i++;
+ }
+ }
}
- g_strfreev(values);
- values = NULL;
+ create_instance_from_pkgkit_data(pk_pkg, pk_det, &sw_pkg, cb, ns, &w);
+ KReturnInstance(cr, w);
- a2i = 0;
- for (j = i * PK_DETAILS_LIMIT;
- j < (i + 1) * PK_DETAILS_LIMIT && j < array->len; j++) {
- pk_pkg = g_ptr_array_index(array, j);
- if (create_sw_package_from_pk_pkg(pk_pkg, &sw_pkg) != 0) {
- continue;
- }
+ free_sw_package(&sw_pkg);
+ }
- cmpres = -1;
- if (array2) {
- while (cmpres < 0 && a2i < array2->len) {
- pk_det = g_ptr_array_index(array2, a2i);
- cmpres = strcmp(pk_details_get_package_id(pk_det),
- pk_package_get_id(pk_pkg));
- if (cmpres < 0) {
- /* this should not happen -
- * we have spare unmatched package details */
- a2i++;
- } else if (cmpres > 0) {
- /* no matching package details for current pk_pkg */
- pk_det = NULL;
- } else {
- /* found a match */
- a2i++;
- }
- }
- }
+done:
+ if (det_array) {
+ g_ptr_array_unref(det_array);
+ }
+ if (pkg_array) {
+ g_ptr_array_unref(pkg_array);
+ }
- create_instance_from_pkgkit_data(pk_pkg, pk_det, &sw_pkg, cb, ns, &w);
- KReturnInstance(cr, w);
+ return;
+}
- free_sw_package(&sw_pkg);
- }
+/*******************************************************************************
+ * Functions related to PkRepos
+ ******************************************************************************/
- if (results) {
- g_object_unref(results);
- results = NULL;
+void get_pk_repo(const char *repo_id_p, PkRepoDetail **repo_p, char *error_msg,
+ const unsigned error_msg_len)
+{
+ guint i;
+ gchar *repo_id = NULL;
+ PkRepoDetail *r;
+ GPtrArray *array = NULL;
+
+ get_pk_repos(&array, error_msg, error_msg_len);
+ if (!array) {
+ warn(error_msg);
+ goto done;
+ }
+
+ for (i = 0; i < array->len; i++) {
+ r = g_ptr_array_index(array, i);
+ g_object_get(r, "repo-id", &repo_id, NULL);
+ if (!repo_id) {
+ continue;
}
- if (array2) {
- g_ptr_array_unref(array2);
- array2 = NULL;
+ if (strcmp(repo_id, repo_id_p) == 0) {
+ *repo_p = g_object_ref(r);
+ break;
}
+ g_free(repo_id);
+ repo_id = NULL;
+ }
+
+done:
+ if (repo_id) {
+ g_free(repo_id);
+ }
+
+ if (array) {
+ g_ptr_array_unref(array);
+ }
+
+ return;
+}
+
+void get_pk_repos(GPtrArray **garray, char *error_msg,
+ const unsigned error_msg_len)
+{
+ PkTask *task = NULL;
+ PkResults *results = NULL;
+ GError *gerror = NULL;
+ GPtrArray *array = NULL;
+
+ task = pk_task_new();
+
+ results = pk_task_get_repo_list_sync(task, 0, NULL, NULL, NULL, &gerror);
+ if (check_and_create_error_msg(results, gerror,
+ "Getting list of repositories failed", error_msg, error_msg_len)) {
+ goto done;
}
+ array = pk_results_get_repo_detail_array(results);
+ g_ptr_array_sort(array, (GCompareFunc) pk_repo_cmp);
+ *garray = g_ptr_array_ref(array);
+
done:
g_clear_error(&gerror);
if (array) {
g_ptr_array_unref(array);
}
+ if (results) {
+ g_object_unref(results);
+ }
if (task) {
g_object_unref(task);
}
@@ -551,6 +689,88 @@ done:
return;
}
+void get_repo_id_from_sw_pkg(const SwPackage *sw_pkg, gchar **repo_id_p,
+ char *error_msg, const unsigned error_msg_len)
+{
+ PkPackage *pk_pkg = NULL;
+ GPtrArray *repos = NULL, *det_array = NULL;
+ gchar *repo_id = NULL, *pkg_id = NULL, **values = NULL, **pkg_id_parts = NULL;
+ const gchar *repo_id_pkg = NULL, *pkg_id_c = NULL;
+ unsigned i, j;
+
+ get_pk_repos(&repos, error_msg, error_msg_len);
+ if (!repos) {
+ goto done;
+ }
+
+ get_pk_pkg_from_sw_pkg(sw_pkg, 0, &pk_pkg);
+ if (!pk_pkg) {
+ goto done;
+ }
+
+ repo_id_pkg = pk_package_get_data(pk_pkg);
+ if (!repo_id_pkg) {
+ warn("Invalid PackageKit package.");
+ goto done;
+ }
+
+ for (i = 0; i < repos->len; i++) {
+ g_object_get(g_ptr_array_index(repos, i), "repo_id", &repo_id, NULL);
+ if (strcmp(repo_id, repo_id_pkg) == 0) {
+ *repo_id_p = repo_id;
+ goto done;
+ }
+ g_free(repo_id);
+ repo_id = NULL;
+ }
+
+ /* We didn't find the match - package is probably installed.. */
+ j = 0;
+ values = g_new0(gchar*, repos->len + 1);
+ for (i = 0; i < repos->len; i++) {
+ g_object_get(g_ptr_array_index(repos, i), "repo_id", &repo_id, NULL);
+ pkg_id = pk_package_id_build(pk_package_get_name(pk_pkg),
+ pk_package_get_version(pk_pkg), pk_package_get_arch(pk_pkg),
+ repo_id);
+ values[j++] = pkg_id;
+
+ g_free(repo_id);
+ repo_id = NULL;
+ }
+
+ get_pk_det_from_array(values, &det_array, NULL);
+
+ if (det_array && det_array->len > 0) {
+ for (i = 0; i < det_array->len; i++) {
+ pkg_id_c = pk_details_get_package_id(g_ptr_array_index(det_array, i));
+ pkg_id_parts = pk_package_id_split(pkg_id_c);
+ if (!pkg_id_parts) {
+ continue;
+ }
+ if (!(*repo_id_p = g_strdup(pkg_id_parts[PK_PACKAGE_ID_DATA]))) {
+ warn("Memory allocation failed.");
+ }
+ goto done;
+ }
+ }
+
+done:
+ g_strfreev(values);
+ g_strfreev(pkg_id_parts);
+
+ if (pk_pkg) {
+ g_object_unref(pk_pkg);
+ }
+ if (repos) {
+ g_ptr_array_unref(repos);
+ }
+ if (det_array) {
+ g_ptr_array_unref(det_array);
+ }
+
+ return;
+}
+
/*******************************************************************************
* Functions related to PackageKit
******************************************************************************/
@@ -607,6 +827,46 @@ gint pk_det_cmp(gpointer a, gpointer b)
return (gint) strcmp(pk_details_get_package_id(al), pk_details_get_package_id(bl));
}
+gint pk_repo_cmp(gpointer a, gpointer b)
+{
+ gint res;
+ PkRepoDetail *al = *(PkRepoDetail **) a;
+ PkRepoDetail *bl = *(PkRepoDetail **) b;
+ gchar *repo_id_a = NULL, *repo_id_b = NULL;
+
+ g_object_get(al, "repo-id", &repo_id_a, NULL);
+ g_object_get(bl, "repo-id", &repo_id_b, NULL);
+
+ res = (gint) strcmp(repo_id_a, repo_id_b);
+
+ g_free(repo_id_a);
+ g_free(repo_id_b);
+
+ return res;
+}
+
+/*******************************************************************************
+ * Functions related to Glib
+ ******************************************************************************/
+
+void gc_gobject_ptr_array_append(GPtrArray **a, const GPtrArray *b)
+{
+ guint i;
+
+ if (!a || !b) {
+ warn("Received empty parameter.");
+ return;
+ }
+
+ if (!*a) {
+ *a = g_ptr_array_new_full(b->len, g_object_unref);
+ }
+
+ for (i = 0; i < b->len; i++) {
+ g_ptr_array_add(*a, g_object_ref(g_ptr_array_index(b, i)));
+ }
+}
+
/*******************************************************************************
* Functions related to CMPI
******************************************************************************/