diff options
author | Peter Schiffer <pschiffe@redhat.com> | 2014-06-18 18:41:30 +0200 |
---|---|---|
committer | Peter Schiffer <pschiffe@redhat.com> | 2014-06-19 14:11:23 +0200 |
commit | 5ac44480df709b9f38922125ae80083bbe7ec1c5 (patch) | |
tree | 253bcb7f3d0b2f0448f02101e0f0d5df04e6d9a4 | |
parent | 469dda76664aff6086aab764493f68074be8e4f8 (diff) | |
download | openlmi-providers-5ac44480df709b9f38922125ae80083bbe7ec1c5.tar.gz openlmi-providers-5ac44480df709b9f38922125ae80083bbe7ec1c5.tar.xz openlmi-providers-5ac44480df709b9f38922125ae80083bbe7ec1c5.zip |
software-dbus: implemented LMI_SoftwareIdentityChecksProvider
-rw-r--r-- | src/libs/libopenlmi/openlmi.h | 2 | ||||
-rw-r--r-- | src/software-dbus/LMI_SoftwareIdentityChecksProvider.c | 388 | ||||
-rw-r--r-- | src/software-dbus/sw-utils.c | 108 | ||||
-rw-r--r-- | src/software-dbus/sw-utils.h | 28 |
4 files changed, 476 insertions, 50 deletions
diff --git a/src/libs/libopenlmi/openlmi.h b/src/libs/libopenlmi/openlmi.h index 8999ace..3609489 100644 --- a/src/libs/libopenlmi/openlmi.h +++ b/src/libs/libopenlmi/openlmi.h @@ -53,6 +53,8 @@ #define LMI_INSTALLED_SOFTWARE "InstalledSoftware" #define LMI_AVAILABLE_SAP "AvailableSAP" #define LMI_MANAGED_ELEMENT "ManagedElement" +#define LMI_ELEMENT "Element" +#define LMI_CHECK "Check" /* CMPI_RC_ERR_<error> values end at 200. 0xFF should be safe. */ #define LMI_RC_ERR_CLASS_CHECK_FAILED 0xFF diff --git a/src/software-dbus/LMI_SoftwareIdentityChecksProvider.c b/src/software-dbus/LMI_SoftwareIdentityChecksProvider.c index b615d95..e000305 100644 --- a/src/software-dbus/LMI_SoftwareIdentityChecksProvider.c +++ b/src/software-dbus/LMI_SoftwareIdentityChecksProvider.c @@ -1,10 +1,33 @@ +/* + * Copyright (C) 2013-2014 Red Hat, Inc. All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Authors: Peter Schiffer <pschiffe@redhat.com> + */ + #include <konkret/konkret.h> #include "LMI_SoftwareIdentityChecks.h" +#include "sw-utils.h" +#include "config.h" static const CMPIBroker* _cb; -static void LMI_SoftwareIdentityChecksInitialize() +static void LMI_SoftwareIdentityChecksInitialize(const CMPIContext *ctx) { + lmi_init(provider_name, _cb, ctx, provider_config_defaults); } static CMPIStatus LMI_SoftwareIdentityChecksCleanup( @@ -21,8 +44,7 @@ static CMPIStatus LMI_SoftwareIdentityChecksEnumInstanceNames( const CMPIResult* cr, const CMPIObjectPath* cop) { - return KDefaultEnumerateInstanceNames( - _cb, mi, cc, cr, cop); + CMReturn(CMPI_RC_ERR_NOT_SUPPORTED); } static CMPIStatus LMI_SoftwareIdentityChecksEnumInstances( @@ -32,7 +54,7 @@ static CMPIStatus LMI_SoftwareIdentityChecksEnumInstances( const CMPIObjectPath* cop, const char** properties) { - CMReturn(CMPI_RC_OK); + CMReturn(CMPI_RC_ERR_NOT_SUPPORTED); } static CMPIStatus LMI_SoftwareIdentityChecksGetInstance( @@ -42,8 +64,34 @@ static CMPIStatus LMI_SoftwareIdentityChecksGetInstance( const CMPIObjectPath* cop, const char** properties) { - return KDefaultGetInstance( - _cb, mi, cc, cr, cop, properties); +#ifndef RPM_FOUND + CMReturn(CMPI_RC_ERR_NOT_SUPPORTED); +#else + const char *elem_name, *file_name, *sw_elem_name; + + LMI_SoftwareIdentityChecks w; + LMI_SoftwareIdentityChecks_InitFromObjectPath(&w, _cb, cop); + + elem_name = lmi_get_string_property_from_objectpath(w.Check.value, + "SoftwareElementID"); + file_name = lmi_get_string_property_from_objectpath(w.Check.value, "Name"); + + sw_elem_name = get_elem_name_from_instance_id( + lmi_get_string_property_from_objectpath(w.Element.value, + "InstanceID")); + + if (strcmp(elem_name, sw_elem_name) != 0) { + CMReturn(CMPI_RC_ERR_NOT_FOUND); + } + + if (!is_file_part_of_elem_name(file_name, elem_name)) { + CMReturn(CMPI_RC_ERR_NOT_FOUND); + } + + KReturnInstance(cr, w); + + CMReturn(CMPI_RC_OK); +#endif } static CMPIStatus LMI_SoftwareIdentityChecksCreateInstance( @@ -95,6 +143,148 @@ static CMPIStatus LMI_SoftwareIdentityChecksAssociationCleanup( CMReturn(CMPI_RC_OK); } +static CMPIStatus associators( + const CMPIContext* cc, + const CMPIResult* cr, + const CMPIObjectPath* cop, + const char* assocClass, + const char* resultClass, + const char* role, + const char* resultRole, + const char** properties, + const short names) +{ +#ifdef RPM_FOUND + CMPIStatus st; + SwPackage sw_pkg; + PkPackage *pk_pkg = NULL; + GStrv files = NULL; + char error_msg[BUFLEN] = "", instance_id[BUFLEN] = ""; + + init_sw_package(&sw_pkg); + + st = lmi_class_path_is_a(_cb, KNameSpace(cop), + LMI_SoftwareIdentityChecks_ClassName, assocClass); + lmi_return_if_class_check_not_ok(st); + + if (CMClassPathIsA(_cb, cop, LMI_SoftwareIdentity_ClassName, &st)) { + /* got SoftwareIdentity - Element */ + unsigned i = 0; + char sw_pkg_elem_name[BUFLEN] = "", sw_pkg_ver_str[BUFLEN] = ""; + + st = lmi_class_path_is_a(_cb, KNameSpace(cop), + LMI_SoftwareIdentityFileCheck_ClassName, resultClass); + lmi_return_if_class_check_not_ok(st); + + if (role && strcmp(role, LMI_ELEMENT) != 0) { + goto done; + } + if (resultRole && strcmp(resultRole, LMI_CHECK) != 0) { + goto done; + } + + create_instance_id(LMI_SoftwareIdentityFileCheck_ClassName, NULL, + instance_id, BUFLEN); + + if (get_sw_pkg_from_sw_identity_op(cop, &sw_pkg) != 0) { + snprintf(error_msg, BUFLEN, "Failed to create software identity."); + goto done; + } + sw_pkg_get_element_name(&sw_pkg, sw_pkg_elem_name, BUFLEN); + sw_pkg_get_version_str(&sw_pkg, sw_pkg_ver_str, BUFLEN); + + get_pk_pkg_from_sw_pkg(&sw_pkg, + pk_bitfield_value(PK_FILTER_ENUM_INSTALLED), &pk_pkg); + if (!pk_pkg) { + goto done; + } + + get_files_of_pk_pkg(pk_pkg, &files, error_msg, BUFLEN); + if (!files) { + goto done; + } + + while (files[i]) { + LMI_SoftwareIdentityFileCheckRef sifc; + LMI_SoftwareIdentityFileCheckRef_Init(&sifc, _cb, KNameSpace(cop)); + LMI_SoftwareIdentityFileCheckRef_Set_CheckID(&sifc, instance_id); + LMI_SoftwareIdentityFileCheckRef_Set_SoftwareElementState(&sifc, + LMI_SoftwareIdentityFileCheckRef_SoftwareElementState_Executable); + LMI_SoftwareIdentityFileCheckRef_Set_TargetOperatingSystem(&sifc, + LMI_SoftwareIdentityFileCheckRef_TargetOperatingSystem_LINUX); + LMI_SoftwareIdentityFileCheckRef_Set_SoftwareElementID(&sifc, + sw_pkg_elem_name); + LMI_SoftwareIdentityFileCheckRef_Set_Version(&sifc, sw_pkg_ver_str); + LMI_SoftwareIdentityFileCheckRef_Set_Name(&sifc, files[i++]); + + if (names) { + KReturnObjectPath(cr, sifc); + } else { + CMPIObjectPath *o = LMI_SoftwareIdentityFileCheckRef_ToObjectPath( + &sifc, &st); + CMPIInstance *ci = _cb->bft->getInstance(_cb, cc, o, properties, + &st); + CMReturnInstance(cr, ci); + } + } + } else if (CMClassPathIsA(_cb, cop, LMI_SoftwareIdentityFileCheck_ClassName, + &st)) { + /* got SoftwareIdentityFileCheck - Check */ + const char *elem_name, *file_name; + + st = lmi_class_path_is_a(_cb, KNameSpace(cop), + LMI_SoftwareIdentity_ClassName, resultClass); + lmi_return_if_class_check_not_ok(st); + + if (role && strcmp(role, LMI_CHECK) != 0) { + goto done; + } + if (resultRole && strcmp(resultRole, LMI_ELEMENT) != 0) { + goto done; + } + + /* Is file part of this package? */ + elem_name = lmi_get_string_property_from_objectpath(cop, + "SoftwareElementID"); + file_name = lmi_get_string_property_from_objectpath(cop, "Name"); + if (!is_file_part_of_elem_name(file_name, elem_name)) { + goto done; + } + + create_instance_id(LMI_SoftwareIdentity_ClassName, elem_name, + instance_id, BUFLEN); + + LMI_SoftwareIdentityRef si; + LMI_SoftwareIdentityRef_Init(&si, _cb, KNameSpace(cop)); + LMI_SoftwareIdentityRef_Set_InstanceID(&si, instance_id); + + if (names) { + KReturnObjectPath(cr, si); + } else { + CMPIObjectPath *o = LMI_SoftwareIdentityRef_ToObjectPath(&si, &st); + CMPIInstance *ci = _cb->bft->getInstance(_cb, cc, o, properties,&st); + CMReturnInstance(cr, ci); + } + } + +done: + free_sw_package(&sw_pkg); + + if (files) { + g_strfreev(files); + } + if (pk_pkg) { + g_object_unref(pk_pkg); + } + + if (*error_msg) { + KReturn2(_cb, ERR_FAILED, "%s", error_msg); + } + +#endif + CMReturn(CMPI_RC_OK); +} + static CMPIStatus LMI_SoftwareIdentityChecksAssociators( CMPIAssociationMI* mi, const CMPIContext* cc, @@ -106,18 +296,8 @@ static CMPIStatus LMI_SoftwareIdentityChecksAssociators( const char* resultRole, const char** properties) { - return KDefaultAssociators( - _cb, - mi, - cc, - cr, - cop, - LMI_SoftwareIdentityChecks_ClassName, - assocClass, - resultClass, - role, - resultRole, - properties); + return associators(cc, cr, cop, assocClass, resultClass, role, + resultRole, properties, 0); } static CMPIStatus LMI_SoftwareIdentityChecksAssociatorNames( @@ -130,17 +310,142 @@ static CMPIStatus LMI_SoftwareIdentityChecksAssociatorNames( const char* role, const char* resultRole) { - return KDefaultAssociatorNames( - _cb, - mi, - cc, - cr, - cop, - LMI_SoftwareIdentityChecks_ClassName, - assocClass, - resultClass, - role, - resultRole); + return associators(cc, cr, cop, assocClass, resultClass, role, + resultRole, NULL, 1); +} + +static CMPIStatus references( + const CMPIResult* cr, + const CMPIObjectPath* cop, + const char* assocClass, + const char* role, + const short names) +{ +#ifdef RPM_FOUND + CMPIStatus st; + SwPackage sw_pkg; + PkPackage *pk_pkg = NULL; + GStrv files = NULL; + char error_msg[BUFLEN] = "", instance_id[BUFLEN] = ""; + + init_sw_package(&sw_pkg); + + st = lmi_class_path_is_a(_cb, KNameSpace(cop), + LMI_SoftwareIdentityChecks_ClassName, assocClass); + lmi_return_if_class_check_not_ok(st); + + if (CMClassPathIsA(_cb, cop, LMI_SoftwareIdentity_ClassName, &st)) { + /* got SoftwareIdentity - Element */ + unsigned i = 0; + char sw_pkg_elem_name[BUFLEN] = "", sw_pkg_ver_str[BUFLEN] = ""; + + if (role && strcmp(role, LMI_ELEMENT) != 0) { + goto done; + } + + create_instance_id(LMI_SoftwareIdentityFileCheck_ClassName, NULL, + instance_id, BUFLEN); + + if (get_sw_pkg_from_sw_identity_op(cop, &sw_pkg) != 0) { + snprintf(error_msg, BUFLEN, "Failed to create software identity."); + goto done; + } + sw_pkg_get_element_name(&sw_pkg, sw_pkg_elem_name, BUFLEN); + sw_pkg_get_version_str(&sw_pkg, sw_pkg_ver_str, BUFLEN); + + get_pk_pkg_from_sw_pkg(&sw_pkg, + pk_bitfield_value(PK_FILTER_ENUM_INSTALLED), &pk_pkg); + if (!pk_pkg) { + goto done; + } + + get_files_of_pk_pkg(pk_pkg, &files, error_msg, BUFLEN); + if (!files) { + goto done; + } + + LMI_SoftwareIdentityRef si; + LMI_SoftwareIdentityRef_InitFromObjectPath(&si, _cb, cop); + + while (files[i]) { + LMI_SoftwareIdentityFileCheckRef sifc; + LMI_SoftwareIdentityFileCheckRef_Init(&sifc, _cb, KNameSpace(cop)); + LMI_SoftwareIdentityFileCheckRef_Set_CheckID(&sifc, instance_id); + LMI_SoftwareIdentityFileCheckRef_Set_SoftwareElementState(&sifc, + LMI_SoftwareIdentityFileCheckRef_SoftwareElementState_Executable); + LMI_SoftwareIdentityFileCheckRef_Set_TargetOperatingSystem(&sifc, + LMI_SoftwareIdentityFileCheckRef_TargetOperatingSystem_LINUX); + LMI_SoftwareIdentityFileCheckRef_Set_SoftwareElementID(&sifc, + sw_pkg_elem_name); + LMI_SoftwareIdentityFileCheckRef_Set_Version(&sifc, sw_pkg_ver_str); + LMI_SoftwareIdentityFileCheckRef_Set_Name(&sifc, files[i++]); + + LMI_SoftwareIdentityChecks w; + LMI_SoftwareIdentityChecks_Init(&w, _cb, KNameSpace(cop)); + LMI_SoftwareIdentityChecks_Set_Element(&w, &si); + LMI_SoftwareIdentityChecks_Set_Check(&w, &sifc); + + if (names) { + KReturnObjectPath(cr, w); + } else { + KReturnInstance(cr, w); + } + } + } else if (CMClassPathIsA(_cb, cop, LMI_SoftwareIdentityFileCheck_ClassName, + &st)) { + /* got SoftwareIdentityFileCheck - Check */ + const char *elem_name, *file_name; + + if (role && strcmp(role, LMI_CHECK) != 0) { + goto done; + } + + /* Is file part of this package? */ + elem_name = lmi_get_string_property_from_objectpath(cop, + "SoftwareElementID"); + file_name = lmi_get_string_property_from_objectpath(cop, "Name"); + if (!is_file_part_of_elem_name(file_name, elem_name)) { + goto done; + } + + create_instance_id(LMI_SoftwareIdentity_ClassName, elem_name, + instance_id, BUFLEN); + + LMI_SoftwareIdentityFileCheckRef sifc; + LMI_SoftwareIdentityFileCheckRef_InitFromObjectPath(&sifc, _cb, cop); + + LMI_SoftwareIdentityRef si; + LMI_SoftwareIdentityRef_Init(&si, _cb, KNameSpace(cop)); + LMI_SoftwareIdentityRef_Set_InstanceID(&si, instance_id); + + LMI_SoftwareIdentityChecks w; + LMI_SoftwareIdentityChecks_Init(&w, _cb, KNameSpace(cop)); + LMI_SoftwareIdentityChecks_Set_Element(&w, &si); + LMI_SoftwareIdentityChecks_Set_Check(&w, &sifc); + + if (names) { + KReturnObjectPath(cr, w); + } else { + KReturnInstance(cr, w); + } + } + +done: + free_sw_package(&sw_pkg); + + if (files) { + g_strfreev(files); + } + if (pk_pkg) { + g_object_unref(pk_pkg); + } + + if (*error_msg) { + KReturn2(_cb, ERR_FAILED, "%s", error_msg); + } + +#endif + CMReturn(CMPI_RC_OK); } static CMPIStatus LMI_SoftwareIdentityChecksReferences( @@ -152,16 +457,7 @@ static CMPIStatus LMI_SoftwareIdentityChecksReferences( const char* role, const char** properties) { - return KDefaultReferences( - _cb, - mi, - cc, - cr, - cop, - LMI_SoftwareIdentityChecks_ClassName, - assocClass, - role, - properties); + return references(cr, cop, assocClass, role, 0); } static CMPIStatus LMI_SoftwareIdentityChecksReferenceNames( @@ -172,28 +468,20 @@ static CMPIStatus LMI_SoftwareIdentityChecksReferenceNames( const char* assocClass, const char* role) { - return KDefaultReferenceNames( - _cb, - mi, - cc, - cr, - cop, - LMI_SoftwareIdentityChecks_ClassName, - assocClass, - role); + return references(cr, cop, assocClass, role, 1); } CMInstanceMIStub( LMI_SoftwareIdentityChecks, LMI_SoftwareIdentityChecks, _cb, - LMI_SoftwareIdentityChecksInitialize()) + LMI_SoftwareIdentityChecksInitialize(ctx)) CMAssociationMIStub( LMI_SoftwareIdentityChecks, LMI_SoftwareIdentityChecks, _cb, - LMI_SoftwareIdentityChecksInitialize()) + LMI_SoftwareIdentityChecksInitialize(ctx)) KONKRET_REGISTRATION( "root/cimv2", diff --git a/src/software-dbus/sw-utils.c b/src/software-dbus/sw-utils.c index 01784d5..93966c3 100644 --- a/src/software-dbus/sw-utils.c +++ b/src/software-dbus/sw-utils.c @@ -397,6 +397,114 @@ void create_instance_from_pkgkit_data(PkPackage *pk_pkg, PkDetails *pk_det, return; } +void get_files_of_pk_pkg(PkPackage *pk_pkg, GStrv *files, char *error_msg, + const unsigned error_msg_len) +{ + PkTask *task = NULL; + PkResults *results = NULL; + GError *gerror = NULL; + GPtrArray *array = NULL; + gchar **values = NULL; + + task = pk_task_new(); + + values = g_new0(gchar*, 2); + values[0] = g_strdup(pk_package_get_id(pk_pkg)); + + results = pk_task_get_files_sync(task, values, NULL, NULL, NULL, &gerror); + if (check_and_create_error_msg(results, gerror, + "Getting files of package failed", error_msg, error_msg_len)) { + goto done; + } + + array = pk_results_get_files_array(results); + if (array->len != 1) { + snprintf(error_msg, error_msg_len, "Getting files of package failed"); + goto done; + } + + g_object_get(g_ptr_array_index(array, 0), "files", files, NULL); + +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; +} + +short is_file_part_of_pk_pkg(const char *file, PkPackage *pk_pkg) +{ + short ret = 0; + unsigned i = 0; + GStrv files = NULL; + char error[BUFLEN] = ""; + + get_files_of_pk_pkg(pk_pkg, &files, error, BUFLEN); + if (!files) { + goto done; + } + + while (files[i]) { + if (strcmp(files[i++], file) == 0) { + ret = 1; + break; + } + } + +done: + if (files) { + g_strfreev(files); + } + + if (*error) { + lmi_warn(error); + } + + return ret; +} + +short is_file_part_of_elem_name(const char *file, const char *elem_name) +{ + short ret = 0; + SwPackage sw_pkg; + PkPackage *pk_pkg = NULL; + + init_sw_package(&sw_pkg); + + if (create_sw_package_from_elem_name(elem_name, &sw_pkg) != 0) { + lmi_warn("Failed to create package from element name: %s", elem_name); + goto done; + } + + get_pk_pkg_from_sw_pkg(&sw_pkg, pk_bitfield_value(PK_FILTER_ENUM_INSTALLED), + &pk_pkg); + if (!pk_pkg) { + lmi_warn("Failed to get PkPackage, probably because it's not installed"); + goto done; + } + + ret = is_file_part_of_pk_pkg(file, pk_pkg); + +done: + free_sw_package(&sw_pkg); + + if (pk_pkg) { + g_object_unref(pk_pkg); + } + + return ret; +} + /******************************************************************************* * Functions related to multiple PkPackages ******************************************************************************/ diff --git a/src/software-dbus/sw-utils.h b/src/software-dbus/sw-utils.h index 567ca72..f9e3456 100644 --- a/src/software-dbus/sw-utils.h +++ b/src/software-dbus/sw-utils.h @@ -155,6 +155,34 @@ void create_instance_from_pkgkit_data(PkPackage *pk_pkg, PkDetails *pk_det, SwPackage *sw_pkg, const CMPIBroker *cb, const char *ns, LMI_SoftwareIdentity *w); +/* + * Get files of PkPackage. + * @param pk_pkg PkPackage + * @param files out array containing files of this package; needs to be passed + * to g_strfreev() when not needed + * @param error_msg error message + * @param error_msg_len error message length + */ +void get_files_of_pk_pkg(PkPackage *pk_pkg, GStrv *files, char *error_msg, + const unsigned error_msg_len); + +/* + * Is file part of PkPackage? + * @param file + * @param pk_pkg PkPackage + * @return 1 if file is part of package, 0 otherwise + */ +short is_file_part_of_pk_pkg(const char *file, PkPackage *pk_pkg); + +/* + * Is file part of package defined by element name? Only succeeds when package + * is installed. + * @param file + * @param elem_name package defined by element name + * @return 1 if file is part of package, 0 otherwise + */ +short is_file_part_of_elem_name(const char *file, const char *elem_name); + /******************************************************************************* * Functions related to multiple PkPackages ******************************************************************************/ |