summaryrefslogtreecommitdiff
path: root/src/libimcv/os_info/os_info.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libimcv/os_info/os_info.c')
-rw-r--r--src/libimcv/os_info/os_info.c553
1 files changed, 4 insertions, 549 deletions
diff --git a/src/libimcv/os_info/os_info.c b/src/libimcv/os_info/os_info.c
index 06427575c..258b8b442 100644
--- a/src/libimcv/os_info/os_info.c
+++ b/src/libimcv/os_info/os_info.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2012 Andreas Steffen
+ * Copyright (C) 2012-2014 Andreas Steffen
* HSR Hochschule fuer Technik Rapperswil
*
* This program is free software; you can redistribute it and/or modify it
@@ -15,16 +15,7 @@
#include "os_info.h"
-#include <sys/utsname.h>
-#include <stdio.h>
-#include <stdarg.h>
-
-#include <collections/linked_list.h>
-#include <utils/debug.h>
-
-typedef struct private_os_info_t private_os_info_t;
-
-ENUM(os_type_names, OS_TYPE_UNKNOWN, OS_TYPE_ANDROID,
+ENUM(os_type_names, OS_TYPE_UNKNOWN, OS_TYPE_WINDOWS,
"Unknown",
"Debian",
"Ubuntu",
@@ -33,7 +24,8 @@ ENUM(os_type_names, OS_TYPE_UNKNOWN, OS_TYPE_ANDROID,
"CentOS",
"SUSE",
"Gentoo",
- "Android"
+ "Android",
+ "Windows",
);
ENUM(os_fwd_status_names, OS_FWD_DISABLED, OS_FWD_UNKNOWN,
@@ -49,487 +41,6 @@ ENUM(os_package_state_names, OS_PACKAGE_STATE_UPDATE, OS_PACKAGE_STATE_BLACKLIST
);
/**
- * Private data of an os_info_t object.
- *
- */
-struct private_os_info_t {
-
- /**
- * Public os_info_t interface.
- */
- os_info_t public;
-
- /**
- * OS type
- */
- os_type_t type;
-
- /**
- * OS name
- */
- chunk_t name;
-
- /**
- * OS version
- */
- chunk_t version;
-
-};
-
-METHOD(os_info_t, get_type, os_type_t,
- private_os_info_t *this)
-{
- return this->type;
-}
-
-METHOD(os_info_t, get_name, chunk_t,
- private_os_info_t *this)
-{
- return this->name;
-}
-
-METHOD(os_info_t, get_numeric_version, void,
- private_os_info_t *this, u_int32_t *major, u_int32_t *minor)
-{
- u_char *pos;
-
- if (major)
- {
- *major = atol(this->version.ptr);
- }
- pos = memchr(this->version.ptr, '.', this->version.len);
- if (minor)
- {
- *minor = pos ? atol(pos + 1) : 0;
- }
-}
-
-METHOD(os_info_t, get_version, chunk_t,
- private_os_info_t *this)
-{
- return this->version;
-}
-
-METHOD(os_info_t, get_fwd_status, os_fwd_status_t,
- private_os_info_t *this)
-{
- const char ip_forward[] = "/proc/sys/net/ipv4/ip_forward";
- char buf[2];
- FILE *file;
-
- os_fwd_status_t fwd_status = OS_FWD_UNKNOWN;
-
- file = fopen(ip_forward, "r");
- if (file)
- {
- if (fread(buf, 1, 1, file) == 1)
- {
- switch (buf[0])
- {
- case '0':
- fwd_status = OS_FWD_DISABLED;
- break;
- case '1':
- fwd_status = OS_FWD_ENABLED;
- break;
- default:
- DBG1(DBG_IMC, "\"%s\" returns invalid value ", ip_forward);
- break;
- }
- }
- else
- {
- DBG1(DBG_IMC, "could not read from \"%s\"", ip_forward);
- }
- fclose(file);
- }
- else
- {
- DBG1(DBG_IMC, "failed to open \"%s\"", ip_forward);
- }
-
- return fwd_status;
-}
-
-METHOD(os_info_t, get_uptime, time_t,
- private_os_info_t *this)
-{
- const char proc_uptime[] = "/proc/uptime";
- FILE *file;
- u_int uptime;
-
- file = fopen(proc_uptime, "r");
- if (!file)
- {
- DBG1(DBG_IMC, "failed to open \"%s\"", proc_uptime);
- return 0;
- }
- if (fscanf(file, "%u", &uptime) != 1)
- {
- DBG1(DBG_IMC, "failed to read file \"%s\"", proc_uptime);
- uptime = 0;
- }
- fclose(file);
-
- return uptime;
-}
-
-METHOD(os_info_t, get_setting, chunk_t,
- private_os_info_t *this, char *name)
-{
- FILE *file;
- u_char buf[2048];
- size_t i = 0;
- chunk_t value;
-
- if (!strpfx(name, "/etc/") && !strpfx(name, "/proc/") &&
- !strpfx(name, "/sys/") && !strpfx(name, "/var/"))
- {
- /**
- * In order to guarantee privacy, only settings from the
- * /etc/, /proc/ and /sys/ directories can be retrieved
- */
- DBG1(DBG_IMC, "not allowed to access '%s'", name);
-
- return chunk_empty;
- }
-
- file = fopen(name, "r");
- if (!file)
- {
- DBG1(DBG_IMC, "failed to open '%s'", name);
-
- return chunk_empty;
- }
- while (i < sizeof(buf) && fread(buf + i, 1, 1, file) == 1)
- {
- i++;
- }
- fclose(file);
-
- value = chunk_create(buf, i);
-
- return chunk_clone(value);
-}
-
-typedef struct {
- /**
- * implements enumerator_t
- */
- enumerator_t public;
-
- /**
- * package info pipe stream
- */
- FILE* file;
-
- /**
- * line buffer
- */
- u_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;
- u_char *pos;
- va_list args;
-
- while (TRUE)
- {
- if (!fgets(this->line, sizeof(this->line), this->file))
- {
- return FALSE;
- }
-
- pos = strchr(this->line, '\t');
- if (!pos)
- {
- return FALSE;
- }
- *pos++ = '\0';
-
- if (!streq(this->line, "install ok installed"))
- {
- continue;
- }
- va_start(args, this);
-
- name = va_arg(args, chunk_t*);
- name->ptr = pos;
- pos = strchr(pos, '\t');
- if (!pos)
- {
- va_end(args);
- return FALSE;
- }
- name->len = pos++ - name->ptr;
-
- 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)
-{
- FILE *file;
- const char command[] = "dpkg-query --show --showformat="
- "'${Status}\t${Package}\t${Version}\n'";
- package_enumerator_t *enumerator;
-
- /* Only Debian and Ubuntu package enumeration is currently supported */
- if (this->type != OS_TYPE_DEBIAN && this->type != OS_TYPE_UBUNTU)
- {
- return NULL;
- }
-
- /* Open a pipe stream for reading the output of the dpkg-query commmand */
- file = popen(command, "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 (enumerator_t*)enumerator;
-}
-
-
-METHOD(os_info_t, destroy, void,
- private_os_info_t *this)
-{
- free(this->name.ptr);
- free(this->version.ptr);
- free(this);
-}
-
-#define RELEASE_LSB 0
-#define RELEASE_DEBIAN 1
-
-/**
- * Determine Linux distribution version and hardware platform
- */
-static bool extract_platform_info(os_type_t *type, chunk_t *name,
- chunk_t *version)
-{
- FILE *file;
- u_char buf[BUF_LEN], *pos = buf;
- int len = BUF_LEN - 1;
- os_type_t os_type = OS_TYPE_UNKNOWN;
- chunk_t os_name = chunk_empty;
- chunk_t os_version = chunk_empty;
- char *os_str;
- struct utsname uninfo;
- int i;
-
- /* Linux/Unix distribution release info (from http://linuxmafia.com) */
- const char* releases[] = {
- "/etc/lsb-release", "/etc/debian_version",
- "/etc/SuSE-release", "/etc/novell-release",
- "/etc/sles-release", "/etc/redhat-release",
- "/etc/fedora-release", "/etc/gentoo-release",
- "/etc/slackware-version", "/etc/annvix-release",
- "/etc/arch-release", "/etc/arklinux-release",
- "/etc/aurox-release", "/etc/blackcat-release",
- "/etc/cobalt-release", "/etc/conectiva-release",
- "/etc/debian_release", "/etc/immunix-release",
- "/etc/lfs-release", "/etc/linuxppc-release",
- "/etc/mandrake-release", "/etc/mandriva-release",
- "/etc/mandrakelinux-release", "/etc/mklinux-release",
- "/etc/pld-release", "/etc/redhat_version",
- "/etc/slackware-release", "/etc/e-smith-release",
- "/etc/release", "/etc/sun-release",
- "/etc/tinysofa-release", "/etc/turbolinux-release",
- "/etc/ultrapenguin-release", "/etc/UnitedLinux-release",
- "/etc/va-release", "/etc/yellowdog-release"
- };
-
- const char lsb_distrib_id[] = "DISTRIB_ID=";
- const char lsb_distrib_release[] = "DISTRIB_RELEASE=";
-
- for (i = 0; i < countof(releases); i++)
- {
- file = fopen(releases[i], "r");
- if (!file)
- {
- continue;
- }
-
- /* read release file into buffer */
- fseek(file, 0, SEEK_END);
- len = min(ftell(file), len);
- rewind(file);
- buf[len] = '\0';
- if (fread(buf, 1, len, file) != len)
- {
- DBG1(DBG_IMC, "failed to read file \"%s\"", releases[i]);
- fclose(file);
- return FALSE;
- }
- fclose(file);
-
- DBG1(DBG_IMC, "processing \"%s\" file", releases[i]);
-
- switch (i)
- {
- case RELEASE_LSB:
- {
- /* Determine Distribution ID */
- pos = strstr(buf, lsb_distrib_id);
- if (!pos)
- {
- DBG1(DBG_IMC, "failed to find begin of DISTRIB_ID field");
- return FALSE;
- }
- pos += strlen(lsb_distrib_id);
-
- os_name.ptr = pos;
-
- pos = strchr(pos, '\n');
- if (!pos)
- {
- DBG1(DBG_IMC, "failed to find end of DISTRIB_ID field");
- return FALSE;
- }
- os_name.len = pos - os_name.ptr;
-
- /* Determine Distribution Release */
- pos = strstr(buf, lsb_distrib_release);
- if (!pos)
- {
- DBG1(DBG_IMC, "failed to find begin of DISTRIB_RELEASE field");
- return FALSE;
- }
- pos += strlen(lsb_distrib_release);
-
- os_version.ptr = pos;
-
- pos = strchr(pos, '\n');
- if (!pos)
- {
- DBG1(DBG_IMC, "failed to find end of DISTRIB_RELEASE field");
- return FALSE;
- }
- os_version.len = pos - os_version.ptr;
-
- break;
- }
- case RELEASE_DEBIAN:
- {
- os_type = OS_TYPE_DEBIAN;
-
- os_version.ptr = buf;
- pos = strchr(buf, '\n');
- if (!pos)
- {
- DBG1(DBG_PTS, "failed to find end of release string");
- return FALSE;
- }
-
- os_version.len = pos - os_version.ptr;
-
- break;
- }
- default:
- {
- const char str_release[] = " release ";
-
- os_name.ptr = buf;
-
- pos = strstr(buf, str_release);
- if (!pos)
- {
- DBG1(DBG_IMC, "failed to find release keyword");
- return FALSE;
- }
-
- os_name.len = pos - os_name.ptr;
-
- pos += strlen(str_release);
- os_version.ptr = pos;
-
- pos = strchr(pos, '\n');
- if (!pos)
- {
- DBG1(DBG_IMC, "failed to find end of release string");
- return FALSE;
- }
-
- os_version.len = pos - os_version.ptr;
-
- break;
- }
- }
- break;
- }
-
- if (!os_version.ptr)
- {
- DBG1(DBG_IMC, "no distribution release file found");
- return FALSE;
- }
-
- if (uname(&uninfo) < 0)
- {
- DBG1(DBG_IMC, "could not retrieve machine architecture");
- return FALSE;
- }
-
- /* Try to find a matching OS type based on the OS name */
- if (os_type == OS_TYPE_UNKNOWN)
- {
- os_type = os_type_from_name(os_name);
- }
-
- /* If known use the official OS name */
- if (os_type != OS_TYPE_UNKNOWN)
- {
- os_str = enum_to_name(os_type_names, os_type);
- os_name = chunk_create(os_str, strlen(os_str));
- }
-
- /* copy OS type */
- *type = os_type;
-
- /* copy OS name */
- *name = chunk_clone(os_name);
-
- /* copy OS version and machine architecture */
- *version = chunk_alloc(os_version.len + 1 + strlen(uninfo.machine));
- pos = version->ptr;
- memcpy(pos, os_version.ptr, os_version.len);
- pos += os_version.len;
- *pos++ = ' ';
- memcpy(pos, uninfo.machine, strlen(uninfo.machine));
-
- return TRUE;
-}
-
-/**
* See header
*/
os_type_t os_type_from_name(chunk_t name)
@@ -548,59 +59,3 @@ os_type_t os_type_from_name(chunk_t name)
}
return OS_TYPE_UNKNOWN;
}
-
-/**
- * See header
- */
-os_info_t *os_info_create(void)
-{
- private_os_info_t *this;
- chunk_t name, version;
- os_type_t type;
-
- /* As an option OS name and OS version can be configured manually */
- name.ptr = lib->settings->get_str(lib->settings,
- "%s.imcv.os_info.name", NULL, lib->ns);
- version.ptr = lib->settings->get_str(lib->settings,
- "%s.imcv.os_info.version", NULL, lib->ns);
- if (name.ptr && version.ptr)
- {
- name.len = strlen(name.ptr);
- name = chunk_clone(name);
-
- version.len = strlen(version.ptr);
- version = chunk_clone(version);
-
- type = os_type_from_name(name);
- }
- else
- {
- if (!extract_platform_info(&type, &name, &version))
- {
- return NULL;
- }
- }
- DBG1(DBG_IMC, "operating system name is '%.*s'",
- name.len, name.ptr);
- DBG1(DBG_IMC, "operating system version is '%.*s'",
- version.len, version.ptr);
-
- INIT(this,
- .public = {
- .get_type = _get_type,
- .get_name = _get_name,
- .get_numeric_version = _get_numeric_version,
- .get_version = _get_version,
- .get_fwd_status = _get_fwd_status,
- .get_uptime = _get_uptime,
- .get_setting = _get_setting,
- .create_package_enumerator = _create_package_enumerator,
- .destroy = _destroy,
- },
- .type = type,
- .name = name,
- .version = version,
- );
-
- return &this->public;
-}