X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fuuid.c;h=89c9e7dddbe97ceba2ea8722729aee6df7463588;hb=bb1d857383b85dbc2c37098391d53e2b9261c830;hp=cf23f5b37eea4e6505f62cb8ac37c65def408a07;hpb=76a7816d2c066f2feff5c77e7da58df4dbc982c2;p=collectd.git diff --git a/src/uuid.c b/src/uuid.c index cf23f5b3..89c9e7dd 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,253 +25,242 @@ **/ #include "collectd.h" + #include "common.h" -#include "configfile.h" #include "plugin.h" -#if HAVE_LIBHAL +#if HAVE_SYS_SYSCTL_H +#include +#endif + +#if HAVE_LIBHAL_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) + +static char *uuidfile = NULL; -#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 const char *config_keys[] = {"UUIDFile"}; -static int -looks_like_a_uuid (const char *uuid) -{ - int len; +static int looks_like_a_uuid(const char *uuid) { + int len; - if (!uuid) return 0; + if (!uuid) + return (0); - len = strlen (uuid); + len = strlen(uuid); - if (len < UUID_PRINTABLE_COMPACT_LENGTH) - return 0; + if (len < UUID_PRINTABLE_COMPACT_LENGTH) + return (0); - while (*uuid) { - if (!isxdigit ((int)*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); - if (!dmidecode) { - return NULL; - } - - uuid = uuid_parse_dmidecode(dmidecode); + uuid = uuid_parse_dmidecode(dmidecode); - pclose(dmidecode); - return uuid; + pclose(dmidecode); + return (uuid); } -#if HAVE_LIBHAL +#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]; -#define UUID_PATH "/org/freedesktop/Hal/devices/computer" -#define UUID_PROPERTY "smbios.system.uuid" + mib[0] = CTL_HW; + mib[1] = HW_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 (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]; +#if HAVE_LIBHAL_H - if (!(file = fopen(path, "r"))) { - return NULL; - } +#define UUID_PATH "/org/freedesktop/Hal/devices/computer" +#define UUID_PROPERTY "smbios.system.uuid" - if (!fgets(uuid, sizeof(uuid), file)) { - fclose(file); - return NULL; - } - fclose(file); +static char *uuid_get_from_hal(void) { + LibHalContext *ctx; - return strdup (uuid); + 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); } -static char *uuidfile = NULL; + libhal_ctx_free(ctx); -static char * -uuid_get_local(void) -{ - char *uuid; +bailout_nobus: + if (dbus_error_is_set(&error)) + dbus_error_free(&error); + return (NULL); +} +#endif - /* Check /etc/uuid / UUIDFile before any other method. */ - if ((uuid = uuid_get_from_file(uuidfile ? uuidfile : "/etc/uuid")) != NULL){ - return uuid; - } +static char *uuid_get_from_file(const char *path) { + FILE *file; + char uuid[UUID_PRINTABLE_NORMAL_LENGTH + 1] = ""; -#if HAVE_LIBHAL - if ((uuid = uuid_get_from_hal()) != NULL) { - return uuid; - } + file = fopen(path, "r"); + if (file == NULL) + return (NULL); + + if (!fgets(uuid, sizeof(uuid), file)) { + fclose(file); + return (NULL); + } + fclose(file); + strstripnewline(uuid); + + return (strdup(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); + +#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 HAVE_LIBHAL_H + if ((uuid = uuid_get_from_hal()) != NULL) + return (uuid); +#endif - if ((uuid = uuid_get_from_file("/sys/hypervisor/uuid")) != NULL) { - return uuid; - } + if ((uuid = uuid_get_from_dmidecode()) != NULL) + return (uuid); - return NULL; +#if defined(__linux__) + if ((uuid = uuid_get_from_file("/sys/hypervisor/uuid")) != NULL) + return (uuid); +#endif + + 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; - } - 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); + } + + return (1); } -static int -uuid_init (void) -{ - char *uuid = uuid_get_local (); +static int uuid_init(void) { + char *uuid = uuid_get_local(); - if (uuid) { - sstrncpy (hostname_g, uuid, DATA_MAX_NAME_LEN); - sfree (uuid); - return 0; - } + if (uuid) { + sstrncpy(hostname_g, uuid, DATA_MAX_NAME_LEN); + sfree(uuid); + return (0); + } - WARNING ("uuid: could not read UUID using any known method"); - return 0; + WARNING("uuid: could not read UUID using any known method"); + return (0); } -void module_register (void) -{ - plugin_register_config ("uuid", uuid_config, - config_keys, NR_CONFIG_KEYS); - plugin_register_init ("uuid", uuid_init); +void module_register(void) { + plugin_register_config("uuid", uuid_config, config_keys, + STATIC_ARRAY_SIZE(config_keys)); + plugin_register_init("uuid", uuid_init); } /*