diff options
Diffstat (limited to 'src/libimcv/os_info/os_info.c')
-rw-r--r-- | src/libimcv/os_info/os_info.c | 87 |
1 files changed, 85 insertions, 2 deletions
diff --git a/src/libimcv/os_info/os_info.c b/src/libimcv/os_info/os_info.c index d5fa4b929..02e32b098 100644 --- a/src/libimcv/os_info/os_info.c +++ b/src/libimcv/os_info/os_info.c @@ -17,6 +17,7 @@ #include <sys/utsname.h> #include <stdio.h> +#include <stdarg.h> #include <collections/linked_list.h> #include <utils/debug.h> @@ -182,12 +183,94 @@ METHOD(os_info_t, get_setting, chunk_t, return chunk_clone(value); } +typedef struct { + /** + * implements enumerator_t + */ + enumerator_t public; + + /** + * streamed pipe + */ + FILE* file; + + /** + * line buffer + */ + char line[512]; + +} package_enumerator_t; + +/** + * Implementation of package_enumerator.destroy. + */ +static void package_enumerator_destroy(package_enumerator_t *this) +{ + pclose(this->file); + free(this); +} + +/** + * Implementation of package_enumerator.enumerate + */ +static bool package_enumerator_enumerate(package_enumerator_t *this, ...) +{ + chunk_t *name, *version; + char *pos; + va_list args; + + if (!fgets(this->line, sizeof(this->line), this->file)) + { + return FALSE; + } + va_start(args, this); + + name = va_arg(args, chunk_t*); + name->ptr = this->line; + pos = strchr(this->line, '\t'); + if (!pos) + { + return FALSE; + } + name->len = pos++ - this->line; + + version = va_arg(args, chunk_t*); + version->ptr = pos; + version->len = strlen(pos) - 1; + + va_end(args); + return TRUE; +} + METHOD(os_info_t, create_package_enumerator, enumerator_t*, private_os_info_t *this) { - /* TODO */ + FILE *file; + package_enumerator_t *enumerator; + chunk_t debian = { "Debian", 6 }; + chunk_t ubuntu = { "Ubuntu", 6 }; + + /* Only Debian and Ubuntu package enumeration is currently supported */ + if (!chunk_equals(this->name, debian) && !chunk_equals(this->name, ubuntu)) + { + return NULL; + } + + /* Open a pipe stream for reading the output of the dpkg-query commmand */ + file = popen("/usr/bin/dpkg-query --show", "r"); + if (!file) + { + DBG1(DBG_IMC, "failed to run dpkg command"); + return NULL; + } + + /* Create a package enumerator instance */ + enumerator = malloc_thing(package_enumerator_t); + enumerator->public.enumerate = (void*)package_enumerator_enumerate; + enumerator->public.destroy = (void*)package_enumerator_destroy; + enumerator->file = file; - return NULL; + return (enumerator_t*)enumerator; } |