aboutsummaryrefslogtreecommitdiffstats
path: root/src/libimcv/os_info
diff options
context:
space:
mode:
authorAndreas Steffen <andreas.steffen@strongswan.org>2012-11-04 23:54:36 +0100
committerAndreas Steffen <andreas.steffen@strongswan.org>2012-11-04 23:54:36 +0100
commit3b057d66cf5acdc17a7338a3053b4a445a694712 (patch)
tree3a51bd9d86aad382a8fc0f3bb7b26b2ce3a5c778 /src/libimcv/os_info
parent9d41e0f362ac3ad66d4a683fbde5929ec1c7c1b1 (diff)
downloadstrongswan-3b057d66cf5acdc17a7338a3053b4a445a694712.tar.bz2
strongswan-3b057d66cf5acdc17a7338a3053b4a445a694712.tar.xz
enumerate over installed Debian/Ubuntu packages
Diffstat (limited to 'src/libimcv/os_info')
-rw-r--r--src/libimcv/os_info/os_info.c87
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;
}