2 * collectd - src/uuid.c
3 * Copyright (C) 2007 Red Hat Inc.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the
7 * Free Software Foundation; only version 2 of the License is applicable.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 * Dan Berrange <berrange@redhat.com>
20 * Richard W.M. Jones <rjones@redhat.com>
22 * Derived from UUID detection code by Dan Berrange <berrange@redhat.com>
23 * http://hg.et.redhat.com/virt/daemons/spectre--devel?f=f6e3a1b06433;file=lib/uuid.c
28 #include "configfile.h"
35 #define UUID_RAW_LENGTH 16
36 #define UUID_PRINTABLE_COMPACT_LENGTH (UUID_RAW_LENGTH * 2)
37 #define UUID_PRINTABLE_NORMAL_LENGTH (UUID_PRINTABLE_COMPACT_LENGTH + 4)
39 #define HANDLE_PREFIX "Handle"
40 #define SYSINFO_PREFIX "System Information"
41 #define ALT_SYSINFO_PREFIX "\tSystem Information"
42 #define UUID_PREFIX "\tUUID:"
43 #define ALT_UUID_PREFIX "\t\tUUID:"
46 looks_like_a_uuid (const char *uuid)
54 if (len < UUID_PRINTABLE_COMPACT_LENGTH)
58 if (!isxdigit ((int)*uuid) && *uuid != '-') return 0;
65 uuid_parse_dmidecode(FILE *file)
71 if (!fgets(line, sizeof(line)/sizeof(char), file)) {
74 if (strncmp(line, HANDLE_PREFIX,
75 (sizeof(HANDLE_PREFIX)/sizeof(char))-1) == 0) {
76 /*printf("Got handle %s\n", line);*/
78 } else if (strncmp(line, SYSINFO_PREFIX,
79 (sizeof(SYSINFO_PREFIX)/sizeof(char))-1) == 0) {
80 /*printf("Got system info %s\n", line);*/
82 } else if (strncmp(line, ALT_SYSINFO_PREFIX,
83 (sizeof(ALT_SYSINFO_PREFIX)/sizeof(char))-1) == 0) {
84 /*printf("Got alt system info %s\n", line);*/
89 if (strncmp(line, UUID_PREFIX,
90 (sizeof(UUID_PREFIX)/sizeof(char))-1) == 0) {
91 char *uuid = line + (sizeof(UUID_PREFIX)/sizeof(char));
92 /*printf("Got uuid [%s]\n", uuid);*/
93 if (looks_like_a_uuid (uuid))
96 if (strncmp(line, ALT_UUID_PREFIX,
97 (sizeof(ALT_UUID_PREFIX)/sizeof(char))-1) == 0) {
98 char *uuid = line + (sizeof(ALT_UUID_PREFIX)/sizeof(char));
99 /*printf("Got alt uuid [%s]\n", uuid);*/
100 if (looks_like_a_uuid (uuid))
101 return strdup (uuid);
109 uuid_get_from_dmidecode(void)
111 FILE *dmidecode = popen("dmidecode 2>/dev/null", "r");
118 uuid = uuid_parse_dmidecode(dmidecode);
126 #define UUID_PATH "/org/freedesktop/Hal/devices/computer"
127 #define UUID_PROPERTY "smbios.system.uuid"
130 uuid_get_from_hal(void)
137 dbus_error_init(&error);
139 if (!(con = dbus_bus_get(DBUS_BUS_SYSTEM, &error)) ) {
143 ctx = libhal_ctx_new();
144 libhal_ctx_set_dbus_connection(ctx, con);
146 if (!libhal_ctx_init(ctx, &error)) {
150 if (!libhal_device_property_exists(ctx,
157 char *uuid = libhal_device_get_property_string(ctx,
161 if (looks_like_a_uuid (uuid)) {
168 dbus_error_init(&ctxerror);
169 if (!(libhal_ctx_shutdown(ctx, &ctxerror))) {
170 dbus_error_free(&ctxerror);
174 libhal_ctx_free(ctx);
175 //dbus_connection_unref(con);
178 if (dbus_error_is_set(&error)) {
179 /*printf("Error %s\n", error.name);*/
180 dbus_error_free(&error);
187 uuid_get_from_file(const char *path)
190 char uuid[UUID_PRINTABLE_NORMAL_LENGTH+1];
192 if (!(file = fopen(path, "r"))) {
196 if (!fgets(uuid, sizeof(uuid), file)) {
202 return strdup (uuid);
205 static char *uuidfile = NULL;
212 /* Check /etc/uuid / UUIDFile before any other method. */
213 if ((uuid = uuid_get_from_file(uuidfile ? uuidfile : "/etc/uuid")) != NULL){
218 if ((uuid = uuid_get_from_hal()) != NULL) {
223 if ((uuid = uuid_get_from_dmidecode()) != NULL) {
227 if ((uuid = uuid_get_from_file("/sys/hypervisor/uuid")) != NULL) {
234 static const char *config_keys[] = {
238 #define NR_CONFIG_KEYS ((sizeof config_keys / sizeof config_keys[0]) - 1)
241 uuid_config (const char *key, const char *value)
243 if (strcasecmp (key, "UUIDFile") == 0) {
245 ERROR ("UUIDFile given twice in configuration file");
248 uuidfile = strdup (value);
257 char *uuid = uuid_get_local ();
260 sstrncpy (hostname_g, uuid, DATA_MAX_NAME_LEN);
265 WARNING ("uuid: could not read UUID using any known method");
269 void module_register (void)
271 plugin_register_config ("uuid", uuid_config,
272 config_keys, NR_CONFIG_KEYS);
273 plugin_register_init ("uuid", uuid_init);
277 * vim: set tabstop=4:
278 * vim: set shiftwidth=4:
279 * vim: set expandtab:
283 * indent-tabs-mode: nil