Skip to content
Snippets Groups Projects
Commit c1857cd8 authored by Michal Privoznik's avatar Michal Privoznik
Browse files

libosinfo example

parent 103acc0b
No related branches found
No related tags found
No related merge requests found
06/main.c 0 → 100644
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include <getopt.h>
#include <osinfo/osinfo.h>
#define ERROR(...) \
do { \
fprintf(stderr, "ERROR %s:%d : ", __FUNCTION__, __LINE__); \
fprintf(stderr, __VA_ARGS__); \
fprintf(stderr, "\n"); \
} while (0)
#define NULLSTR(s) \
((s) ? (s) : "")
typedef struct _Control Control;
struct _Control {
const char *db_path;
const char *os_id;
const char *detect_path;
bool list_os_ids;
};
static void
print_libosinfo_version(void)
{
printf("libosinfo version: %d.%d.%d\n",
OSINFO_MAJOR_VERSION,
OSINFO_MINOR_VERSION,
OSINFO_MICRO_VERSION);
}
static void
print_help(const char *progname)
{
printf("\n"
"%s [options] [<ID>]\n"
"\n"
" options:\n"
" -v | --version print libosinfo version and exit\n"
" -h | --help print this help and exit\n"
" -p | --db-path <PATH> where to load libosinfo DB from\n"
" -i | --os-id <ID> OS identifier (short or long)\n"
" -l | --list list OS identifiers and exit\n"
" -d | --detect <PATH> detect OS from given path\n",
progname);
}
static int
parseArgv(Control *ctl,
int argc,
char *argv[])
{
int ret = -1;
int arg;
int longindex = -1;
const char *progname = NULL;
struct option opt[] = {
{ "version", no_argument, NULL, 'v' },
{ "help", no_argument, NULL, 'h' },
{ "db-path", required_argument, NULL, 'p' },
{ "os-id", required_argument, NULL, 'i' },
{ "list", no_argument, NULL, 'l' },
{ "detect", required_argument, NULL, 'd' },
{ NULL, 0, NULL, 0 },
};
progname = strrchr(argv[0], '/');
if (!progname) {
progname = argv[0];
} else {
progname++;
}
while ((arg = getopt_long(argc, argv, ":vhp:ild:", opt, &longindex)) != -1) {
switch (arg) {
case 'v':
print_libosinfo_version();
exit(EXIT_SUCCESS);
break;
case 'h':
print_help(progname);
exit(EXIT_SUCCESS);
break;
case 'p':
ctl->db_path = optarg;
break;
case 'i':
ctl->os_id = optarg;
break;
case 'l':
ctl->list_os_ids = true;
break;
case 'd':
ctl->detect_path = optarg;
break;
case '?':
if (optopt)
ERROR("unsupported option '-%1$c'. See --help.", optopt);
else
ERROR("unsupported option '%1$s'. See --help.", argv[optind - 1]);
goto cleanup;
default:
ERROR("unknown option");
goto cleanup;
}
longindex = -1;
}
if (argc != optind) {
if (ctl->os_id || optind + 1 != argc) {
ERROR("Too much args");
goto cleanup;
}
ctl->os_id = argv[optind];
}
if (ctl->detect_path && ctl->os_id) {
ERROR("--os-id and --detect are mutually exclusive");
goto cleanup;
}
ret = 0;
cleanup:
return ret;
}
static OsinfoDb *
load_db(Control *ctl)
{
g_autoptr(OsinfoLoader) loader = osinfo_loader_new();
GError *error = NULL;
if (ctl->db_path) {
osinfo_loader_process_path(loader, ctl->db_path, &error);
} else {
osinfo_loader_process_default_path(loader, &error);
}
if (error) {
ERROR(error->message);
return NULL;
}
return g_object_ref(osinfo_loader_get_db(loader));
}
static gint
sort_entity(gconstpointer a,
gconstpointer b,
gpointer data)
{
OsinfoEntity *entityA = OSINFO_ENTITY((gpointer) a);
OsinfoEntity *entityB = OSINFO_ENTITY((gpointer) b);
gchar *key = data;
const gchar *valA;
const gchar *valB;
valA = osinfo_entity_get_param_value(entityA, key);
valB = osinfo_entity_get_param_value(entityB, key);
if (!valA && !valB)
return 0;
if (!valA && valB)
return 1;
if (valA && !valB)
return 1;
return strcmp(valA, valB);
}
#define FMT_STRING "%25s\t%-50s\t%-10s\t%s\n"
static void
list_os_ids(OsinfoDb *db)
{
g_autoptr(OsinfoOsList) list = osinfo_db_get_os_list(db);
g_autoptr(GList) entities = osinfo_list_get_elements(OSINFO_LIST(list));
GList *tmp;
tmp = entities = g_list_sort_with_data(entities, sort_entity,
OSINFO_PRODUCT_PROP_SHORT_ID);
printf(FMT_STRING, "Short ID", "Name", "Version", "ID");
/* No match */
if (tmp == NULL)
return;
while (tmp) {
OsinfoEntity *entity = OSINFO_ENTITY(tmp->data);
const char *shortID = osinfo_entity_get_param_value(entity, OSINFO_PRODUCT_PROP_SHORT_ID);
const char *name = osinfo_entity_get_param_value(entity, OSINFO_PRODUCT_PROP_NAME);
const char *version = osinfo_entity_get_param_value(entity, OSINFO_PRODUCT_PROP_VERSION);
const char *id = osinfo_entity_get_param_value(entity, OSINFO_ENTITY_PROP_ID);
printf(FMT_STRING, NULLSTR(shortID), NULLSTR(name), NULLSTR(version), NULLSTR(id));
tmp = tmp->next;
}
}
#undef FMT_STRING
static OsinfoOs *
find_os_from_path(Control *ctl,
OsinfoDb *db)
{
g_autoptr(OsinfoMedia) media = NULL;
GError *error = NULL;
OsinfoOs *os = NULL;
g_autoptr(OsinfoMediaList) matched = NULL;
media = osinfo_media_create_from_location(ctl->detect_path, NULL, &error);
if (error) {
ERROR(error->message);
return NULL;
}
matched = osinfo_db_identify_medialist(db, media);
if (osinfo_list_get_length(OSINFO_LIST(matched)) > 0) {
OsinfoMedia *newmedia = OSINFO_MEDIA(osinfo_list_get_nth(OSINFO_LIST(matched), 0));
g_object_get(G_OBJECT(newmedia), "os", &os, NULL);
if (os) {
return os;
}
}
ERROR("Unable to find OS from: %s", ctl->detect_path);
return NULL;
}
static OsinfoOs *
find_os(Control *ctl,
OsinfoDb *db)
{
OsinfoOs *os = NULL;
g_autoptr(OsinfoOsList) oslist = NULL;
g_autoptr(OsinfoFilter) filter = NULL;
g_autoptr(OsinfoOsList) filteredList = NULL;
if (!ctl->os_id) {
ERROR("No OS specified");
return NULL;
}
if ((os = osinfo_db_get_os(db, ctl->os_id))) {
return g_object_ref(os);
}
oslist = osinfo_db_get_os_list(db);
filter = osinfo_filter_new();
osinfo_filter_add_constraint(filter,
OSINFO_PRODUCT_PROP_SHORT_ID,
ctl->os_id);
filteredList = OSINFO_OSLIST(osinfo_list_new_filtered(OSINFO_LIST(oslist),
filter));
if (osinfo_list_get_length(OSINFO_LIST(filteredList)) > 0) {
os = OSINFO_OS(osinfo_list_get_nth(OSINFO_LIST(filteredList), 0));
return g_object_ref(os);
}
ERROR("Unable to find OS: %s", ctl->os_id);
return NULL;
}
#define PRINT_POSITIVE(val, ...) \
do { \
typeof(val) _v = val; \
if (_v > 0) { \
printf(__VA_ARGS__, _v); \
} \
} while (0)
static void
print_one_resource(OsinfoResources *res)
{
PRINT_POSITIVE(osinfo_resources_get_n_cpus(res),
"N CPUs: %d\n");
PRINT_POSITIVE(osinfo_resources_get_cpu(res) / OSINFO_MEGAHERTZ,
"CPU freq: %" G_GINT64_FORMAT " MHz\n");
PRINT_POSITIVE(osinfo_resources_get_ram(res) / OSINFO_MEBIBYTES,
"Memory: %" G_GINT64_FORMAT " MiB\n");
PRINT_POSITIVE(osinfo_resources_get_storage(res) / OSINFO_GIBIBYTES,
"Storage: %" G_GINT64_FORMAT " GiB\n");
printf("\n");
}
#undef PRINT_POSITIVE
static int
print_resources(Control *ctl,
OsinfoOs *os)
{
OsinfoResourcesList *resources_list;
OsinfoResources *resources;
resources_list = osinfo_os_get_minimum_resources(os);
if (resources_list && osinfo_list_get_length(OSINFO_LIST(resources_list)) > 0) {
resources = OSINFO_RESOURCES(osinfo_list_get_nth(OSINFO_LIST(resources_list), 0));
printf("Minimum resources\n");
print_one_resource(resources);
}
g_clear_object(&resources_list);
resources_list = osinfo_os_get_recommended_resources(os);
if (resources_list && osinfo_list_get_length(OSINFO_LIST(resources_list)) > 0) {
resources = OSINFO_RESOURCES(osinfo_list_get_nth(OSINFO_LIST(resources_list), 0));
printf("Recommended resources\n");
print_one_resource(resources);
}
g_clear_object(&resources_list);
resources_list = osinfo_os_get_maximum_resources(os);
if (resources_list && osinfo_list_get_length(OSINFO_LIST(resources_list)) > 0) {
resources = OSINFO_RESOURCES(osinfo_list_get_nth(OSINFO_LIST(resources_list), 0));
printf("Maximum resources\n");
print_one_resource(resources);
}
g_clear_object(&resources_list);
resources_list = osinfo_os_get_network_install_resources(os);
if (resources_list && osinfo_list_get_length(OSINFO_LIST(resources_list)) > 0) {
resources = OSINFO_RESOURCES(osinfo_list_get_nth(OSINFO_LIST(resources_list), 0));
printf("Network install resources\n");
print_one_resource(resources);
}
g_clear_object(&resources_list);
return 0;
}
int
main(int argc, char *argv[])
{
Control ctl = { };
g_autoptr(OsinfoDb) db = NULL;
g_autoptr(OsinfoOs) os = NULL;
if (parseArgv(&ctl, argc, argv) < 0) {
return EXIT_FAILURE;
}
if (!(db = load_db(&ctl))) {
return EXIT_FAILURE;
}
if (ctl.list_os_ids) {
list_os_ids(db);
return EXIT_SUCCESS;
}
if (ctl.detect_path) {
os = find_os_from_path(&ctl, db);
} else {
os = find_os(&ctl, db);
}
if (!os) {
return EXIT_FAILURE;
}
if (print_resources(&ctl, os) < 0) {
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
project('osinfo', 'c', default_options : ['c_std=gnu18'])
libosinfo_dep = dependency('libosinfo-1.0')
executable('osinfo', 'main.c', dependencies: [libosinfo_dep])
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment