X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=src%2Fuuid.c;h=89766268740aa7f7a40ab81bbdb21c40e8ed35e4;hb=141816828389e3ad98f66db29b4a702479dcb05d;hp=e0de0d9b314ed53575b7e5f00b08921a03834642;hpb=597adb008e5cb9b39bc925046d2aedc084ec2b9e;p=collectd.git diff --git a/src/uuid.c b/src/uuid.c index e0de0d9b..89766268 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,11 +25,16 @@ **/ #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 @@ -36,92 +42,106 @@ #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 const char *config_keys[] = { + "UUIDFile" +}; static int looks_like_a_uuid (const char *uuid) { int len; - if (!uuid) return 0; + if (!uuid) + return (0); len = strlen (uuid); if (len < UUID_PRINTABLE_COMPACT_LENGTH) - return 0; + return (0); while (*uuid) { - if (!isxdigit (*uuid) && *uuid != '-') return 0; + if (!isxdigit ((int)*uuid) && *uuid != '-') + return (0); uuid++; } - return 1; + 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); - } - } + + 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; + return (NULL); } static char * uuid_get_from_dmidecode(void) { - FILE *dmidecode = popen("dmidecode 2>/dev/null", "r"); + 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); pclose(dmidecode); - return uuid; + return (uuid); +} + +#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]; -#if HAVE_LIBHAL + mib[0] = CTL_HW; + mib[1] = HW_UUID; + + if (sysctl(mib, 2, uuid, &len, NULL, 0) == -1) + return NULL; + return (strdup (uuid)); +} +#endif + +#if HAVE_LIBHAL_H #define UUID_PATH "/org/freedesktop/Hal/devices/computer" #define UUID_PROPERTY "smbios.system.uuid" @@ -136,50 +156,42 @@ uuid_get_from_hal(void) dbus_error_init(&error); - if (!(con = dbus_bus_get(DBUS_BUS_SYSTEM, &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)) { + if (!libhal_ctx_init(ctx, &error)) goto bailout; - } if (!libhal_device_property_exists(ctx, UUID_PATH, UUID_PROPERTY, - &error)) { + &error)) goto bailout; - } char *uuid = libhal_device_get_property_string(ctx, UUID_PATH, UUID_PROPERTY, &error); - if (looks_like_a_uuid (uuid)) { - return uuid; - } + if (looks_like_a_uuid (uuid)) + return (uuid); bailout: { DBusError ctxerror; dbus_error_init(&ctxerror); - if (!(libhal_ctx_shutdown(ctx, &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);*/ + if (dbus_error_is_set(&error)) dbus_error_free(&error); - } - return NULL; + return (NULL); } #endif @@ -187,68 +199,77 @@ static char * uuid_get_from_file(const char *path) { FILE *file; - char uuid[UUID_PRINTABLE_NORMAL_LENGTH+1]; + 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; + return (NULL); } fclose(file); + strstripnewline (uuid); - return strdup (uuid); + return (strdup (uuid)); } -static char *uuidfile = NULL; - 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 ((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 HAVE_LIBHAL - if ((uuid = uuid_get_from_hal()) != NULL) { - return uuid; - } +#if HAVE_LIBHAL_H + if ((uuid = uuid_get_from_hal()) != 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; + char *tmp = strdup (value); + if (tmp == NULL) + return (-1); + sfree (uuidfile); + uuidfile = tmp; + return (0); } - return 0; + + return (1); } static int @@ -259,18 +280,18 @@ uuid_init (void) if (uuid) { sstrncpy (hostname_g, uuid, DATA_MAX_NAME_LEN); sfree (uuid); - return 0; + return (0); } WARNING ("uuid: could not read UUID using any known method"); - return 0; + return (0); } void module_register (void) { - plugin_register_config ("uuid", uuid_config, - config_keys, NR_CONFIG_KEYS); - plugin_register_init ("uuid", uuid_init); + plugin_register_config ("uuid", uuid_config, + config_keys, STATIC_ARRAY_SIZE (config_keys)); + plugin_register_init ("uuid", uuid_init); } /*