X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fuuid.c;h=816e624a0cb29ef1ace6e61925a513d0bbde9f3d;hb=da11ce02eb202b3e01d3e2d1b40f248a84430973;hp=e0de0d9b314ed53575b7e5f00b08921a03834642;hpb=2c2e9a297f59c110ddd4adef6293fe80f39f15b7;p=collectd.git diff --git a/src/uuid.c b/src/uuid.c index e0de0d9b..1cb90270 100644 --- a/src/uuid.c +++ b/src/uuid.c @@ -1,6 +1,7 @@ /** * collectd - src/uuid.c * Copyright (C) 2007 Red Hat Inc. + * Copyright (C) 2015 Ruben Kerkhof * * 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 @@ -24,265 +25,185 @@ **/ #include "collectd.h" + #include "common.h" -#include "configfile.h" #include "plugin.h" -#if HAVE_LIBHAL -#include +#if HAVE_SYS_SYSCTL_H +#include #endif #define UUID_RAW_LENGTH 16 -#define UUID_PRINTABLE_COMPACT_LENGTH (UUID_RAW_LENGTH * 2) -#define UUID_PRINTABLE_NORMAL_LENGTH (UUID_PRINTABLE_COMPACT_LENGTH + 4) +#define UUID_PRINTABLE_COMPACT_LENGTH (UUID_RAW_LENGTH * 2) +#define UUID_PRINTABLE_NORMAL_LENGTH (UUID_PRINTABLE_COMPACT_LENGTH + 4) -#define HANDLE_PREFIX "Handle" -#define SYSINFO_PREFIX "System Information" -#define ALT_SYSINFO_PREFIX "\tSystem Information" -#define UUID_PREFIX "\tUUID:" -#define ALT_UUID_PREFIX "\t\tUUID:" +static char *uuidfile = NULL; -static int -looks_like_a_uuid (const char *uuid) -{ - int len; +static const char *config_keys[] = {"UUIDFile"}; - if (!uuid) return 0; +static int looks_like_a_uuid(const char *uuid) { + int len; - len = strlen (uuid); + if (!uuid) + return 0; - if (len < UUID_PRINTABLE_COMPACT_LENGTH) - return 0; + len = strlen(uuid); + + if (len < UUID_PRINTABLE_COMPACT_LENGTH) + return 0; - while (*uuid) { - if (!isxdigit (*uuid) && *uuid != '-') return 0; - uuid++; - } - return 1; + while (*uuid) { + if (!isxdigit((int)*uuid) && *uuid != '-') + return 0; + uuid++; + } + return 1; } -static char * -uuid_parse_dmidecode(FILE *file) -{ - char line[1024]; - int inSysInfo = 0; - - for (;;) { - if (!fgets(line, sizeof(line)/sizeof(char), file)) { - return NULL; - } - if (strncmp(line, HANDLE_PREFIX, - (sizeof(HANDLE_PREFIX)/sizeof(char))-1) == 0) { - /*printf("Got handle %s\n", line);*/ - inSysInfo = 0; - } else if (strncmp(line, SYSINFO_PREFIX, - (sizeof(SYSINFO_PREFIX)/sizeof(char))-1) == 0) { - /*printf("Got system info %s\n", line);*/ - inSysInfo = 1; - } else if (strncmp(line, ALT_SYSINFO_PREFIX, - (sizeof(ALT_SYSINFO_PREFIX)/sizeof(char))-1) == 0) { - /*printf("Got alt system info %s\n", line);*/ - inSysInfo = 1; - } - - if (inSysInfo) { - if (strncmp(line, UUID_PREFIX, - (sizeof(UUID_PREFIX)/sizeof(char))-1) == 0) { - char *uuid = line + (sizeof(UUID_PREFIX)/sizeof(char)); - /*printf("Got uuid [%s]\n", uuid);*/ - if (looks_like_a_uuid (uuid)) - return strdup (uuid); - } - if (strncmp(line, ALT_UUID_PREFIX, - (sizeof(ALT_UUID_PREFIX)/sizeof(char))-1) == 0) { - char *uuid = line + (sizeof(ALT_UUID_PREFIX)/sizeof(char)); - /*printf("Got alt uuid [%s]\n", uuid);*/ - if (looks_like_a_uuid (uuid)) - return strdup (uuid); - } - } - } - return NULL; +static char *uuid_parse_dmidecode(FILE *file) { + char line[1024]; + + while (fgets(line, sizeof(line), file) != NULL) { + char *fields[4]; + int fields_num; + + strstripnewline(line); + + /* Look for a line reading: + * UUID: XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX + */ + fields_num = strsplit(line, fields, STATIC_ARRAY_SIZE(fields)); + if (fields_num != 2) + continue; + + if (strcmp("UUID:", fields[0]) != 0) + continue; + + if (!looks_like_a_uuid(fields[1])) + continue; + + return strdup(fields[1]); + } + return NULL; } -static char * -uuid_get_from_dmidecode(void) -{ - FILE *dmidecode = popen("dmidecode 2>/dev/null", "r"); - char *uuid; +static char *uuid_get_from_dmidecode(void) { + FILE *dmidecode = popen("dmidecode -t system 2>/dev/null", "r"); + char *uuid; - if (!dmidecode) { - return NULL; - } - - uuid = uuid_parse_dmidecode(dmidecode); + if (!dmidecode) + return NULL; - pclose(dmidecode); - return uuid; + uuid = uuid_parse_dmidecode(dmidecode); + + pclose(dmidecode); + return uuid; } -#if HAVE_LIBHAL - -#define UUID_PATH "/org/freedesktop/Hal/devices/computer" -#define UUID_PROPERTY "smbios.system.uuid" - -static char * -uuid_get_from_hal(void) -{ - LibHalContext *ctx; - - DBusError error; - DBusConnection *con; - - dbus_error_init(&error); - - if (!(con = dbus_bus_get(DBUS_BUS_SYSTEM, &error)) ) { - goto bailout_nobus; - } - - ctx = libhal_ctx_new(); - libhal_ctx_set_dbus_connection(ctx, con); - - if (!libhal_ctx_init(ctx, &error)) { - goto bailout; - } - - if (!libhal_device_property_exists(ctx, - UUID_PATH, - UUID_PROPERTY, - &error)) { - goto bailout; - } - - char *uuid = libhal_device_get_property_string(ctx, - UUID_PATH, - UUID_PROPERTY, - &error); - if (looks_like_a_uuid (uuid)) { - return uuid; - } - - bailout: - { - DBusError ctxerror; - dbus_error_init(&ctxerror); - if (!(libhal_ctx_shutdown(ctx, &ctxerror))) { - dbus_error_free(&ctxerror); - } - } - - libhal_ctx_free(ctx); - //dbus_connection_unref(con); - - bailout_nobus: - if (dbus_error_is_set(&error)) { - /*printf("Error %s\n", error.name);*/ - dbus_error_free(&error); - } +#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) +static char *uuid_get_from_sysctlbyname(const char *name) { + char uuid[UUID_PRINTABLE_NORMAL_LENGTH + 1]; + size_t len = sizeof(uuid); + if (sysctlbyname(name, &uuid, &len, NULL, 0) == -1) + return NULL; + return strdup(uuid); +} +#elif defined(__OpenBSD__) +static char *uuid_get_from_sysctl(void) { + char uuid[UUID_PRINTABLE_NORMAL_LENGTH + 1]; + size_t len = sizeof(uuid); + int mib[2]; + + mib[0] = CTL_HW; + mib[1] = HW_UUID; + + if (sysctl(mib, 2, uuid, &len, NULL, 0) == -1) return NULL; + return strdup(uuid); } #endif -static char * -uuid_get_from_file(const char *path) -{ - FILE *file; - char uuid[UUID_PRINTABLE_NORMAL_LENGTH+1]; +static char *uuid_get_from_file(const char *path) { + FILE *file; + char uuid[UUID_PRINTABLE_NORMAL_LENGTH + 1] = ""; - if (!(file = fopen(path, "r"))) { - return NULL; - } + file = fopen(path, "r"); + if (file == NULL) + return NULL; - if (!fgets(uuid, sizeof(uuid), file)) { - fclose(file); - return NULL; - } + if (!fgets(uuid, sizeof(uuid), file)) { fclose(file); + return NULL; + } + fclose(file); + strstripnewline(uuid); - return strdup (uuid); + return strdup(uuid); } -static char *uuidfile = NULL; +static char *uuid_get_local(void) { + char *uuid; -static char * -uuid_get_local(void) -{ - char *uuid; - - /* Check /etc/uuid / UUIDFile before any other method. */ - if ((uuid = uuid_get_from_file(uuidfile ? uuidfile : "/etc/uuid")) != NULL){ - return uuid; - } + /* Check /etc/uuid / UUIDFile before any other method. */ + if ((uuid = uuid_get_from_file(uuidfile ? uuidfile : "/etc/uuid")) != NULL) + return uuid; -#if HAVE_LIBHAL - if ((uuid = uuid_get_from_hal()) != NULL) { - return uuid; - } +#if defined(__APPLE__) + if ((uuid = uuid_get_from_sysctlbyname("kern.uuid")) != NULL) + return uuid; +#elif defined(__FreeBSD__) + if ((uuid = uuid_get_from_sysctlbyname("kern.hostuuid")) != NULL) + return uuid; +#elif defined(__NetBSD__) + if ((uuid = uuid_get_from_sysctlbyname("machdep.dmi.system-uuid")) != NULL) + return uuid; +#elif defined(__OpenBSD__) + if ((uuid = uuid_get_from_sysctl()) != NULL) + return uuid; +#elif defined(__linux__) + if ((uuid = uuid_get_from_file("/sys/class/dmi/id/product_uuid")) != NULL) + return uuid; #endif - if ((uuid = uuid_get_from_dmidecode()) != NULL) { - return uuid; - } + if ((uuid = uuid_get_from_dmidecode()) != NULL) + return uuid; - if ((uuid = uuid_get_from_file("/sys/hypervisor/uuid")) != NULL) { - return uuid; - } +#if defined(__linux__) + if ((uuid = uuid_get_from_file("/sys/hypervisor/uuid")) != NULL) + return uuid; +#endif - return NULL; + return NULL; } -static const char *config_keys[] = { - "UUIDFile", - NULL -}; -#define NR_CONFIG_KEYS ((sizeof config_keys / sizeof config_keys[0]) - 1) - -static int -uuid_config (const char *key, const char *value) -{ - if (strcasecmp (key, "UUIDFile") == 0) { - if (uuidfile) { - ERROR ("UUIDFile given twice in configuration file"); - return 1; - } - uuidfile = strdup (value); - return 0; - } +static int uuid_config(const char *key, const char *value) { + if (strcasecmp(key, "UUIDFile") == 0) { + char *tmp = strdup(value); + if (tmp == NULL) + return -1; + sfree(uuidfile); + uuidfile = tmp; return 0; -} + } -static int -uuid_init (void) -{ - char *uuid = uuid_get_local (); + return 1; +} - if (uuid) { - sstrncpy (hostname_g, uuid, DATA_MAX_NAME_LEN); - sfree (uuid); - return 0; - } +static int uuid_init(void) { + char *uuid = uuid_get_local(); - WARNING ("uuid: could not read UUID using any known method"); + if (uuid) { + hostname_set(uuid); + sfree(uuid); return 0; -} + } -void module_register (void) -{ - plugin_register_config ("uuid", uuid_config, - config_keys, NR_CONFIG_KEYS); - plugin_register_init ("uuid", uuid_init); + WARNING("uuid: could not read UUID using any known method"); + return 0; } -/* - * vim: set tabstop=4: - * vim: set shiftwidth=4: - * vim: set expandtab: - */ -/* - * Local variables: - * indent-tabs-mode: nil - * c-indent-level: 4 - * c-basic-offset: 4 - * tab-width: 4 - * End: - */ +void module_register(void) { + plugin_register_config("uuid", uuid_config, config_keys, + STATIC_ARRAY_SIZE(config_keys)); + plugin_register_init("uuid", uuid_init); +}