/**
* collectd - src/battery.c
* Copyright (C) 2006,2007 Florian octo Forster
+ * Copyright (C) 2008 Michał Mirosław
*
* 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
*
* Authors:
* Florian octo Forster <octo at verplant.org>
+ * Michał Mirosław <mirq-linux at rere.qmqm.pl>
**/
#include "collectd.h"
#include "common.h"
#include "plugin.h"
+#include "utils_complain.h"
+
#if HAVE_MACH_MACH_TYPES_H
# include <mach/mach_types.h>
#endif
#elif KERNEL_LINUX
static int battery_pmu_num = 0;
static char *battery_pmu_file = "/proc/pmu/battery_%i";
+static const char *battery_acpi_dir = "/proc/acpi/battery";
#endif /* KERNEL_LINUX */
static int battery_init (void)
for (battery_pmu_num = 0; ; battery_pmu_num++)
{
- len = snprintf (filename, sizeof (filename), battery_pmu_file, battery_pmu_num);
+ len = ssnprintf (filename, sizeof (filename), battery_pmu_file, battery_pmu_num);
if ((len < 0) || ((unsigned int)len >= sizeof (filename)))
break;
vl.values = values;
vl.values_len = 1;
vl.time = time (NULL);
- strcpy (vl.host, hostname_g);
- strcpy (vl.plugin, "battery");
- strcpy (vl.plugin_instance, plugin_instance);
+ sstrncpy (vl.host, hostname_g, sizeof (vl.host));
+ sstrncpy (vl.plugin, "battery", sizeof (vl.plugin));
+ sstrncpy (vl.plugin_instance, plugin_instance, sizeof (vl.plugin_instance));
+ sstrncpy (vl.type, type, sizeof (vl.type));
- plugin_dispatch_values (type, &vl);
+ plugin_dispatch_values (&vl);
} /* void battery_submit */
#if HAVE_IOKIT_PS_IOPOWERSOURCES_H || HAVE_IOKIT_IOKITLIB_H
}
#endif /* HAVE_IOKIT_IOKITLIB_H */
+#if KERNEL_LINUX
+static int battery_read_acpi (const char *dir, const char *name,
+ void *user_data)
+{
+ double current = INVALID_VALUE;
+ double voltage = INVALID_VALUE;
+ double charge = INVALID_VALUE;
+ double *valptr = NULL;
+ int charging = 0;
+
+ char filename[256];
+ FILE *fh;
+
+ char buffer[1024];
+ char *fields[8];
+ int numfields;
+ char *endptr;
+ int len;
+
+ len = ssnprintf (filename, sizeof (filename), "%s/%s/state", battery_acpi_dir, name);
+
+ if ((len < 0) || ((unsigned int)len >= sizeof (filename)))
+ return -1;
+
+ if ((fh = fopen (filename, "r")) == NULL) {
+ char errbuf[1024];
+ ERROR ("Cannot open `%s': %s", filename,
+ sstrerror (errno, errbuf, sizeof (errbuf)));
+ return -1;
+ }
+
+ /*
+ * [11:00] <@tokkee> $ cat /proc/acpi/battery/BAT1/state
+ * [11:00] <@tokkee> present: yes
+ * [11:00] <@tokkee> capacity state: ok
+ * [11:00] <@tokkee> charging state: charging
+ * [11:00] <@tokkee> present rate: 1724 mA
+ * [11:00] <@tokkee> remaining capacity: 4136 mAh
+ * [11:00] <@tokkee> present voltage: 12428 mV
+ */
+ while (fgets (buffer, sizeof (buffer), fh) != NULL)
+ {
+ numfields = strsplit (buffer, fields, 8);
+
+ if (numfields < 3)
+ continue;
+
+ if ((strcmp (fields[0], "charging") == 0)
+ && (strcmp (fields[1], "state:") == 0))
+ {
+ if (strcmp (fields[2], "charging") == 0)
+ charging = 1;
+ else
+ charging = 0;
+ continue;
+ }
+
+ if ((strcmp (fields[0], "present") == 0)
+ && (strcmp (fields[1], "rate:") == 0))
+ valptr = ¤t;
+ else if ((strcmp (fields[0], "remaining") == 0)
+ && (strcmp (fields[1], "capacity:") == 0))
+ valptr = &charge;
+ else if ((strcmp (fields[0], "present") == 0)
+ && (strcmp (fields[1], "voltage:") == 0))
+ valptr = &voltage;
+ else
+ continue;
+
+ endptr = NULL;
+ errno = 0;
+ *valptr = strtod (fields[2], &endptr) / 1000.0;
+
+ if ((fields[2] == endptr) || (errno != 0))
+ *valptr = INVALID_VALUE;
+ } /* while (fgets (buffer, sizeof (buffer), fh) != NULL) */
+
+ fclose (fh);
+
+ if ((current != INVALID_VALUE) && (charging == 0))
+ current *= -1;
+
+ if (charge != INVALID_VALUE)
+ battery_submit ("0", "charge", charge);
+ if (current != INVALID_VALUE)
+ battery_submit ("0", "current", current);
+ if (voltage != INVALID_VALUE)
+ battery_submit ("0", "voltage", voltage);
+
+ return 0;
+}
+#endif /* KERNEL_LINUX */
+
+
static int battery_read (void)
{
#if HAVE_IOKIT_IOKITLIB_H || HAVE_IOKIT_PS_IOPOWERSOURCES_H
/* #endif HAVE_IOKIT_IOKITLIB_H || HAVE_IOKIT_PS_IOPOWERSOURCES_H */
#elif KERNEL_LINUX
+ static c_complain_t acpi_dir_complaint = C_COMPLAIN_INIT;
+
FILE *fh;
char buffer[1024];
char filename[256];
double charge = INVALID_VALUE;
double *valptr = NULL;
- len = snprintf (filename, sizeof (filename), battery_pmu_file, i);
+ len = ssnprintf (filename, sizeof (filename), battery_pmu_file, i);
if ((len < 0) || ((unsigned int)len >= sizeof (filename)))
continue;
- len = snprintf (batnum_str, sizeof (batnum_str), "%i", i);
+ len = ssnprintf (batnum_str, sizeof (batnum_str), "%i", i);
if ((len < 0) || ((unsigned int)len >= sizeof (batnum_str)))
continue;
battery_submit ("0", "voltage", voltage);
}
- if (access ("/proc/acpi/battery", R_OK | X_OK) == 0)
+ if (0 == access (battery_acpi_dir, R_OK))
+ walk_directory (battery_acpi_dir, battery_read_acpi,
+ /* user_data = */ NULL);
+ else
{
- double current = INVALID_VALUE;
- double voltage = INVALID_VALUE;
- double charge = INVALID_VALUE;
- double *valptr = NULL;
- int charging = 0;
-
- struct dirent *ent;
- DIR *dh;
-
- if ((dh = opendir ("/proc/acpi/battery")) == NULL)
- {
- char errbuf[1024];
- ERROR ("Cannot open `/proc/acpi/battery': %s",
- sstrerror (errno, errbuf, sizeof (errbuf)));
- return (-1);
- }
-
- while ((ent = readdir (dh)) != NULL)
- {
- if (ent->d_name[0] == '.')
- continue;
-
- len = snprintf (filename, sizeof (filename),
- "/proc/acpi/battery/%s/state",
- ent->d_name);
- if ((len < 0) || ((unsigned int)len >= sizeof (filename)))
- continue;
-
- if ((fh = fopen (filename, "r")) == NULL)
- {
- char errbuf[1024];
- ERROR ("Cannot open `%s': %s", filename,
- sstrerror (errno, errbuf,
- sizeof (errbuf)));
- continue;
- }
-
- /*
- * [11:00] <@tokkee> $ cat /proc/acpi/battery/BAT1/state
- * [11:00] <@tokkee> present: yes
- * [11:00] <@tokkee> capacity state: ok
- * [11:00] <@tokkee> charging state: charging
- * [11:00] <@tokkee> present rate: 1724 mA
- * [11:00] <@tokkee> remaining capacity: 4136 mAh
- * [11:00] <@tokkee> present voltage: 12428 mV
- */
- while (fgets (buffer, sizeof (buffer), fh) != NULL)
- {
- numfields = strsplit (buffer, fields, 8);
-
- if (numfields < 3)
- continue;
-
- if ((strcmp (fields[0], "present") == 0)
- && (strcmp (fields[1], "rate:") == 0))
- valptr = ¤t;
- else if ((strcmp (fields[0], "remaining") == 0)
- && (strcmp (fields[1], "capacity:") == 0))
- valptr = &charge;
- else if ((strcmp (fields[0], "present") == 0)
- && (strcmp (fields[1], "voltage:") == 0))
- valptr = &voltage;
- else
- valptr = NULL;
-
- if ((strcmp (fields[0], "charging") == 0)
- && (strcmp (fields[1], "state:") == 0))
- {
- if (strcmp (fields[2], "charging") == 0)
- charging = 1;
- else
- charging = 0;
- }
-
- if (valptr != NULL)
- {
- char *endptr;
-
- endptr = NULL;
- errno = 0;
-
- *valptr = strtod (fields[2], &endptr) / 1000.0;
-
- if ((fields[2] == endptr) || (errno != 0))
- *valptr = INVALID_VALUE;
- }
- } /* while (fgets (buffer, sizeof (buffer), fh) != NULL) */
-
- fclose (fh);
-
- if ((current != INVALID_VALUE) && (charging == 0))
- current *= -1;
-
- if (charge != INVALID_VALUE)
- battery_submit ("0", "charge", charge);
- if (current != INVALID_VALUE)
- battery_submit ("0", "current", current);
- if (voltage != INVALID_VALUE)
- battery_submit ("0", "voltage", voltage);
- }
-
- closedir (dh);
+ char errbuf[1024];
+ c_complain_once (LOG_WARNING, &acpi_dir_complaint,
+ "battery plugin: Failed to access `%s': %s",
+ battery_acpi_dir,
+ sstrerror (errno, errbuf, sizeof (errbuf)));
}
+
#endif /* KERNEL_LINUX */
return (0);