diff options
author | Andreas Steffen <andreas.steffen@strongswan.org> | 2012-10-10 21:54:05 +0200 |
---|---|---|
committer | Andreas Steffen <andreas.steffen@strongswan.org> | 2012-10-10 21:54:21 +0200 |
commit | 6ab1502519025e2bd05d01d49fe3d0f1ce8d6bd6 (patch) | |
tree | b851d0b12249cefd3bdbec8efac1e0f8d5c4e175 /src/libimcv/os_info | |
parent | 7f3bf2b12f81e85c9a0a66c6bcc5c2b44db66b49 (diff) | |
download | strongswan-6ab1502519025e2bd05d01d49fe3d0f1ce8d6bd6.tar.bz2 strongswan-6ab1502519025e2bd05d01d49fe3d0f1ce8d6bd6.tar.xz |
implemented os_info_t class
Diffstat (limited to 'src/libimcv/os_info')
-rw-r--r-- | src/libimcv/os_info/os_info.c | 309 | ||||
-rw-r--r-- | src/libimcv/os_info/os_info.h | 65 |
2 files changed, 374 insertions, 0 deletions
diff --git a/src/libimcv/os_info/os_info.c b/src/libimcv/os_info/os_info.c new file mode 100644 index 000000000..4dbcee55f --- /dev/null +++ b/src/libimcv/os_info/os_info.c @@ -0,0 +1,309 @@ +/* + * Copyright (C) 2012 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include "os_info.h" + +#include <sys/utsname.h> + +#include <utils/linked_list.h> +#include <debug.h> + + +typedef struct private_os_info_t private_os_info_t; + + +/** + * Private data of an os_info_t object. + * + */ +struct private_os_info_t { + + /** + * Public os_info_t interface. + */ + os_info_t public; + + /** + * OS name + */ + chunk_t name; + + /** + * OS version + */ + chunk_t version; + +}; + +METHOD(os_info_t, get_name, chunk_t, + private_os_info_t *this) +{ + return this->name; +} + +METHOD(os_info_t, get_version, chunk_t, + private_os_info_t *this) +{ + return this->version; +} + +METHOD(os_info_t, create_package_enumerator, enumerator_t*, + private_os_info_t *this) +{ + /* TODO */ + return NULL; +} + + +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(chunk_t *name, chunk_t *version) +{ + FILE *file; + u_char buf[BUF_LEN], *pos = buf; + int len = BUF_LEN - 1; + chunk_t os_name = chunk_empty; + chunk_t os_version = chunk_empty; + 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: + { + char str_debian[] = "Debian"; + + os_name = chunk_create(str_debian, strlen(str_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_name.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; + } + + /* 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_info_t *os_info_create(void) +{ + private_os_info_t *this; + chunk_t name, version; + + /* As an opton OS name and OS version can be configured manually */ + name.ptr = lib->settings->get_str(lib->settings, + "libimcv.os_info.name", NULL); + version.ptr = lib->settings->get_str(lib->settings, + "libimcv.os_info.version", NULL); + if (name.ptr && version.ptr) + { + name.len = strlen(name.ptr); + name = chunk_clone(name); + + version.len = strlen(version.ptr); + version = chunk_clone(version); + } + else + { + if (!extract_platform_info(&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_name = _get_name, + .get_version = _get_version, + .create_package_enumerator = _create_package_enumerator, + .destroy = _destroy, + }, + .name = name, + .version = version, + ); + + return &this->public; +} diff --git a/src/libimcv/os_info/os_info.h b/src/libimcv/os_info/os_info.h new file mode 100644 index 000000000..78d0509f4 --- /dev/null +++ b/src/libimcv/os_info/os_info.h @@ -0,0 +1,65 @@ +/* + * Copyright (C) 2012 Andreas Steffen + * HSR Hochschule fuer Technik Rapperswil + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +/** + * @defgroup os_info os_info + * @{ @ingroup libimcv + */ + +#ifndef OS_INFO_H_ +#define OS_INFO_H_ + +typedef struct os_info_t os_info_t; + +#include <library.h> + +/** + * Interface for the Operating System (OS) information module + */ +struct os_info_t { + + /** + * Get the OS product name or distribution + * + * @return OS name + */ + chunk_t (*get_name)(os_info_t *this); + + /** + * Get the OS version or release + * + * @return OS version + */ + chunk_t (*get_version)(os_info_t *this); + + /** + * Enumerates over all installed packages + * + * @return return package enumerator + */ + enumerator_t* (*create_package_enumerator)(os_info_t *this); + + /** + * Destroys an os_info_t object. + */ + void (*destroy)(os_info_t *this); +}; + +/** + * Create an os_info_t object + */ +os_info_t* os_info_create(void); + +#endif /** OS_INFO_H_ @}*/ |