Skip to content

Instantly share code, notes, and snippets.

@jirihnidek
Created February 27, 2019 13:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jirihnidek/c85e72e8c2a5b21e2813f07939497a64 to your computer and use it in GitHub Desktop.
Save jirihnidek/c85e72e8c2a5b21e2813f07939497a64 to your computer and use it in GitHub Desktop.
Libdnf plugin
CMAKE_MINIMUM_REQUIRED (VERSION 3.11.2)
project(example C)
include(GNUInstallDirs)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_STANDARD 11)
# Build type
if (NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
message(STATUS "Setting build type to 'Debug' as none was specified.")
set(CMAKE_BUILD_TYPE Debug CACHE STRING "Choose the type of build." FORCE)
# Set the possible values of build type for cmake-gui
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS "Debug" "Release")
endif ()
if (CMAKE_COMPILER_IS_GNUCC)
set (CMAKE_C_FLAGS "-Wall -fPIC -Wextra -pedantic -Wno-long-long")
if (CMAKE_BUILD_TYPE STREQUAL "Debug")
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ggdb -O0 --coverage")
elseif( CMAKE_BUILD_TYPE STREQUAL "Release" )
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DNDEBUG -g -O3 -fno-strict-aliasing")
endif ()
endif (CMAKE_COMPILER_IS_GNUCC)
find_package(PkgConfig REQUIRED)
pkg_check_modules(GLIB REQUIRED glib-2.0>=2.44.0)
pkg_check_modules(GIO REQUIRED gio-2.0>=2.54.3)
pkg_check_modules(LIBDNF REQUIRED libdnf>=0.22.0)
include_directories(${GLIB_INCLUDE_DIRS})
include_directories(${GIO_INCLUDE_DIRS})
include_directories(${LIBDNF_INCLUDE_DIRS})
add_library(example SHARED example.c)
# Don't put "lib" on the front
set_target_properties(example PROPERTIES PREFIX "")
target_link_libraries(example
${GLIB_LIBRARIES}
${GIO_LIBRARIES}
${LIBDNF_LIBRARIES}
)
# Note: libdnf use "hardcoded" directory /usr/lib64/libdnf/plugins for searching
# libdnf plugins. This directory cannot be changed by any configuration file ATM.
# It can be changed only during building of libdnf using CMAKE_INSTALL_FULL_LIBDIR
#install(TARGETS example LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}/libdnf/plugins)
install(TARGETS example LIBRARY DESTINATION /usr/lib64/libdnf/plugins)
#include <libdnf/plugin/plugin.h>
#include <libdnf/libdnf.h>
#include <stdio.h>
#define SUPPORTED_LIBDNF_PLUGIN_API_VERSION 1
/**
* Information about libdnf plugin
*/
static const PluginInfo pinfo = {
.name = "Product ID - libdnf Plugin",
.version = "1.0.0"
};
/**
* Structure holding all data specific for this plugin
*/
typedef struct _PluginHandle {
// Data provided by the init method
int version;
PluginMode mode;
DnfContext *context;
// Add plugin-specific "private" data here
} _PluginHandle;
const PluginInfo *pluginGetInfo() {
return &pinfo;
}
/**
* Initialize handle of this plugin
* @param version
* @param mode
* @param initData
* @return
*/
PluginHandle *pluginInitHandle(int version, PluginMode mode, DnfPluginInitData *initData) {
printf("%s initializing handle!\n", pinfo.name);
if (version != SUPPORTED_LIBDNF_PLUGIN_API_VERSION) {
printf("Unsupported version of libdnf plugin API: %d\n", version);
return NULL;
}
if (mode != PLUGIN_MODE_CONTEXT) {
printf("Unsupported mode of libdnf plugin: %d\n", (int)mode);
return NULL;
}
PluginHandle* handle = malloc(sizeof(PluginHandle));
if (handle) {
handle->version = version;
handle->mode = mode;
handle->context = pluginGetContext(initData);
}
return handle;
}
/**
* Free handle and all other private date of handle
* @param handle
*/
void pluginFreeHandle(PluginHandle *handle) {
printf("%s freeing handle!\n", pinfo.name);
if (handle) {
free(handle);
}
}
/**
* Callback function. This method is executed for every libdnf hook. This callback
* is called several times during transaction, but we are interested only in one situation.
*
* @param handle Pointer on structure with data specific for this plugin
* @param id Id of hook (moment of transaction, when this callback is called)
* @param hookData
* @param error
* @return
*/
int pluginHook(PluginHandle *handle, PluginHookId id, DnfPluginHookData *hookData, DnfPluginError *error) {
// We do not need this for anything
(void)error;
(void)hookData;
if (!handle) {
// We must have failed to allocate our handle during init; don't do anything.
return 0;
}
printf("%s v%s, running hook_id: %d on DNF version %d\n",
pinfo.name, pinfo.version, id, handle->version);
if (id == PLUGIN_HOOK_ID_CONTEXT_TRANSACTION) {
printf("Info about loaded repos:\n");
GPtrArray * repos = dnf_context_get_repos(handle->context);
for (unsigned int i = 0; i < repos->len; ++i) {
DnfRepo * repo = g_ptr_array_index(repos, i);
const gchar * repoId = dnf_repo_get_id(repo);
bool enabled = (dnf_repo_get_enabled(repo) & DNF_REPO_ENABLED_PACKAGES) > 0;
printf("Repo: %s enabled: %i\n", repoId, enabled);
}
}
return 1;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment