--- /dev/null
+This package was written by:
+ Florian octo Forster <octo@verplant.org>
+
+cpufreq module by:
+ Peter Holik <peter@holik.at>
+
+hddtemp module by:
+ Vincent Stehlé <vincent.stehle@free.fr>
+
+nfs module by:
+ Jason Pepas <cell@ices.utexas.edu>
+
+processes module by:
+ Lyonel Vincent <lyonel@ezix.org>
+
+quota module by:
+ Niki Waibel <niki.waibel@newlogic.com>
+
+serial module by:
+ David Bacher <drbacher@gmail.com>
+
+tape module by:
+ Scott Garrett <sgarrett@technomancer.com>
+
+don't-fork-patch by:
+ Alvaro Barcellos <alvaro.barcellos@gmail.com>
+
+collectd is available at:
+ <http://verplant.org/collectd/>
+
+Enjoy :)
--- /dev/null
+dnl Process this file with autoconf to produce a configure script.
+AC_INIT(src/collectd.c)
+AM_INIT_AUTOMAKE(collectd, 3.4.0-quota)
+AM_CONFIG_HEADER(src/config.h src/libping/config.h)
+AC_LANG(C)
+
+#AC_PREFIX_DEFAULT("/opt/collectd-3.4.0")
+
+dnl Checks for programs.
+AC_PROG_CC
+AC_PROG_CPP
+AC_PROG_INSTALL
+AC_PROG_LN_S
+AC_PROG_MAKE_SET
+
+dnl configure libtool
+AC_DISABLE_STATIC
+AC_LIBTOOL_DLOPEN
+AC_PROG_LIBTOOL
+#AC_PROG_RANLIB
+
+dnl Checks for header files.
+AC_HEADER_STDC
+AC_HEADER_SYS_WAIT
+AC_CHECK_HEADERS(fcntl.h unistd.h)
+AC_CHECK_HEADERS(signal.h)
+AC_CHECK_HEADERS(sys/socket.h)
+AC_CHECK_HEADERS(sys/select.h)
+AC_CHECK_HEADERS(netdb.h)
+AC_CHECK_HEADERS(sys/time.h sys/times.h)
+AC_CHECK_HEADERS(sys/types.h)
+AC_CHECK_HEADERS(sys/resource.h)
+AC_CHECK_HEADERS(errno.h)
+AC_CHECK_HEADERS(arpa/inet.h)
+AC_CHECK_HEADERS(netinet/in.h)
+AC_CHECK_HEADERS(netdb.h)
+AC_CHECK_HEADERS(syslog.h)
+AC_CHECK_HEADERS(dlfcn.h)
+AC_CHECK_HEADERS(paths.h)
+AC_CHECK_HEADERS(mntent.h)
+AC_CHECK_HEADERS(sys/fs_types.h)
+AC_CHECK_HEADERS(sys/mnttab.h)
+AC_CHECK_HEADERS(sys/mount.h)
+AC_CHECK_HEADERS(sys/vfstab.h)
+AC_CHECK_HEADERS(xfs/xqm.h)
+
+dnl Checking for libraries
+AC_CHECK_LIB(m, ext)
+
+dnl Checks for typedefs, structures, and compiler characteristics.
+AC_C_CONST
+AC_TYPE_PID_T
+AC_TYPE_SIZE_T
+AC_HEADER_TIME
+
+dnl Checks for library functions.
+AC_PROG_GCC_TRADITIONAL
+AC_CHECK_FUNCS(gettimeofday select socket strdup strstr strtol)
+AC_CHECK_FUNCS(socket, , AC_CHECK_LIB(socket, socket))
+AC_CHECK_FUNCS(gethostbyname, , AC_CHECK_LIB(nsl, gethostbyname))
+AC_CHECK_FUNCS(strchr memcpy strstr strcmp strncmp strncpy strlen)
+AC_CHECK_FUNCS(strncasecmp strcasecmp strncmp)
+AC_CHECK_FUNCS(getfsent getvfsent getmntent listmntent)
+
+AC_MSG_CHECKING([for kernel type ($host_os)])
+case $host_os in
+ *linux*)
+ AC_DEFINE([KERNEL_LINUX], [], [True if program is to be compiled for a Linux kernel])
+ ac_system="Linux"
+ ;;
+ *solaris*)
+ AC_DEFINE([KERNEL_SOLARIS], [], [True if program is to be compiled for a Solaris kernel])
+ ac_system="Solaris"
+ ;;
+ *)
+ ac_system="unknown"
+esac
+AC_MSG_RESULT([$ac_system])
+
+dnl Checks for libraries.
+AC_CHECK_LIB(socket, socket)
+AC_CHECK_LIB(resolv, res_search)
+AC_CHECK_LIB(dl, dlopen)
+
+# AC_ARG_WITH (package, help-string, [action-if-given], [action-if-not-given])
+AC_ARG_WITH(rrdtool, AC_HELP_STRING([--with-rrdtool=PFX], [Path to rrdtool.]),
+[ if test "x$withval" != "xno" -a "x$withval" != "xyes"
+ then
+ LDFLAGS="$LDFLAGS -L$withval/lib"
+ CPPFLAGS="$CPPFLAGS -I$withval/include"
+ with_rrdtool="yes"
+ fi
+], [with_rrdtool="yes"])
+if test "x$with_rrdtool" = "xyes"
+then
+ AC_CHECK_LIB(rrd, rrd_update,, [with_rrdtool="no"], [-lm])
+fi
+if test "x$with_rrdtool" = "xyes"
+then
+ AC_CHECK_HEADERS(rrd.h,, [with_rrdtool="no"])
+fi
+AM_CONDITIONAL(BUILD_WITH_RRDTOOL, test "x$with_rrdtool" = "xyes")
+
+if test "$ac_system" = "Solaris"
+then
+ with_kstat="yes"
+ AC_CHECK_LIB(kstat, kstat_open,, [with_kstat="no (not found)"])
+ AC_CHECK_LIB(devinfo, di_init)
+ AC_CHECK_HEADERS(kstat.h,, [with_kstat="no (kstat.h not found)"])
+else
+ with_kstat="no (Solaris only)"
+fi
+
+AC_ARG_WITH(libstatgrab, AC_HELP_STRING([--with-libstatgrab@<:@=PFX@:>@], [Path to libstatgrab.]),
+[
+ # given..
+ if test "x$withval" != "xno"
+ then
+ if test "x$withval" != "xyes"
+ then
+ LDFLAGS="$LDFLAGS -L$withval/lib"
+ CPPFLAGS="$CPPFLAGS -I$withval/include"
+ with_libstatgrab="yes"
+ fi
+ fi
+],
+[
+ # not given..
+ if test "x$ac_system" != "xunknown"
+ then
+ with_libstatgrab="no"
+ else
+ with_libstatgrab="yes"
+ fi
+])
+if test "x$with_libstatgrab" = "xyes"
+then
+ AC_CHECK_LIB(statgrab, sg_init,, [with_libstatgrab="no (not found)"])
+ AC_CHECK_HEADERS(statgrab.h,, [with_libstatgrab="no (not found)"])
+fi
+
+AC_ARG_WITH(lm-sensors, AC_HELP_STRING([--with-lm-sensors@<:@=PFX@:>@], [Path to lm_sensors.]),
+[
+ # given..
+ if test "x$withval" != "xno"
+ then
+ if test "x$withval" != "xyes"
+ then
+ LDFLAGS="$LDFLAGS -L$withval/lib"
+ CPPFLAGS="$CPPFLAGS -I$withval/include"
+ with_lm_sensors="yes"
+ fi
+ fi
+],
+[
+ # not given..
+ if test "x$ac_system" = "xLinux"
+ then
+ with_lm_sensors="yes"
+ else
+ with_lm_sensors="no"
+ fi
+])
+if test "x$with_lm_sensors" = "xyes"
+then
+ AC_CHECK_LIB(sensors, sensors_init,
+ [
+ with_lm_sensors="yes"
+ AC_DEFINE(HAVE_LIBSENSORS, 1, [Define to 1 if you have the sensors library (-lsensors).])
+ ],
+ [with_lm_sensors="no (not found)"])
+ AC_CHECK_HEADERS(sensors/sensors.h,
+ [
+ with_lm_sensors="yes"
+ AC_DEFINE(HAVE_SENSORS_SENSORS_H, 1, [Define to 1 if you have the <sensors/sensors.h> header file.])
+ ],
+ [with_lm_sensors="no (not found)"])
+fi
+
+
+
+#
+# Check for enabled/disabled features
+#
+AC_ARG_ENABLE(cpu, AC_HELP_STRING([--disable-cpu], [Disable CPU usage statistics]),, [enable_cpu="yes"])
+if test "x$enable_cpu" != "xno"
+then
+ if test "x$ac_system" = "xLinux" -o "x$with_kstat" = "xyes" -o "x$with_libstatgrab" = "xyes"
+ then
+ enable_cpu="yes"
+ else
+ enable_cpu="no"
+ fi
+fi
+if test "x$enable_cpu" = "xno"
+then
+ AC_DEFINE(COLLECT_CPU, 0, [Wether or not to collect CPU usage statistics])
+fi
+AM_CONDITIONAL(BUILD_MODULE_CPU, test "x$enable_cpu" = "xyes")
+
+AC_ARG_ENABLE(cpufreq, AC_HELP_STRING([--disable-cpufreq], [Disable system cpu frequency statistics]),, [enable_cpufreq="yes"])
+if test "x$enable_cpufreq" != "xno"
+then
+ if test "x$ac_system" = "xLinux"
+ then
+ enable_cpufreq="yes"
+ else
+ enable_cpufreq="no"
+ fi
+fi
+if test "x$enable_cpufreq" = "xno"
+then
+ AC_DEFINE(COLLECT_CPUFREQ, 0, [Wether or not to collect cpu frequency statistics])
+fi
+AM_CONDITIONAL(BUILD_MODULE_CPUFREQ, test "x$enable_cpufreq" = "xyes")
+
+AC_ARG_ENABLE(disk, AC_HELP_STRING([--disable-disk], [Disable disk/partition statistics]),, [enable_disk="yes"])
+if test "x$enable_disk" != "xno"
+then
+ if test "x$ac_system" = "xLinux" -o "x$with_kstat" = "xyes"
+ then
+ enable_disk="yes"
+ else
+ enable_disk="no"
+ fi
+fi
+if test "x$enable_disk" = "xno"
+then
+ AC_DEFINE(COLLECT_DISK, 0, [Wether or not to collect diskstats])
+fi
+AM_CONDITIONAL(BUILD_MODULE_DISK, test "x$enable_disk" = "xyes")
+
+AC_ARG_ENABLE(quota, AC_HELP_STRING([--enable-quota],
+ [Enable quota statistics (experimental, off by default)]),
+ [], [enable_quota="no"])
+if test "x$enable_quota" = "xno"
+then
+ collect_quota=0
+else
+ if test "x$enable_quota" = "xyes"
+ then
+ collect_quota=1
+ enable_quota="yes"
+ else
+ AC_MSG_NOTICE([Please specify either --enable-quota or --disable-quota; Enabling quota statistics.])
+ collect_quota=1
+ enable_quota="yes"
+ fi
+fi
+AC_DEFINE_UNQUOTED(COLLECT_QUOTA, [$collect_quota],
+ [Wether or not to collect quotastats])
+AM_CONDITIONAL(BUILD_MODULE_QUOTA, test "x$enable_quota" = "xyes")
+
+AC_ARG_ENABLE(hddtemp, AC_HELP_STRING([--disable-hddtemp], [Disable hdd temperature statistics]),, [enable_hddtemp="yes"])
+if test "x$enable_hddtemp" = "xno"
+then
+ AC_DEFINE(COLLECT_HDDTEMP, 0, [Wether or not to collect hdd temperature statistics])
+fi
+AM_CONDITIONAL(BUILD_MODULE_HDDTEMP, test "x$enable_hddtemp" = "xyes")
+
+AC_ARG_ENABLE(load, AC_HELP_STRING([--disable-load], [Disable system load statistics]),, [enable_load="yes"])
+if test "x$enable_load" != "xno"
+then
+ if test "x$ac_system" = "xLinux" -o "x$with_kstat" = "xyes" -o "x$with_libstatgrab" = "xyes"
+ then
+ enable_load="yes"
+ else
+ enable_load="no"
+ fi
+fi
+if test "x$enable_load" = "xno"
+then
+ AC_DEFINE(COLLECT_LOAD, 0, [Wether or not to collect system load statistics])
+fi
+AM_CONDITIONAL(BUILD_MODULE_LOAD, test "x$enable_load" = "xyes")
+
+AC_ARG_ENABLE(memory, AC_HELP_STRING([--disable-memory], [Disable memory statistics]),, [enable_memory="yes"])
+if test "x$enable_memory" != "xno"
+then
+ if test "x$ac_system" = "xLinux" -o "x$with_kstat" = "xyes" -o "x$with_libstatgrab" = "xyes"
+ then
+ enable_memory="yes"
+ else
+ enable_memory="no"
+ fi
+fi
+if test "x$enable_memory" = "xno"
+then
+ AC_DEFINE(COLLECT_MEMORY, 0, [Wether or not to collect memory statistics])
+fi
+AM_CONDITIONAL(BUILD_MODULE_MEMORY, test "x$enable_memory" = "xyes")
+
+AC_ARG_ENABLE(nfs, AC_HELP_STRING([--disable-nfs], [Disable nfs statistics]),, [enable_nfs="yes"])
+if test "x$enable_nfs" != "xno"
+then
+ if test "x$ac_system" = "xLinux"
+ then
+ enable_nfs="yes"
+ else
+ enable_nfs="no"
+ fi
+fi
+if test "x$enable_nfs" = "xno"
+then
+ AC_DEFINE(COLLECT_NFS, 0, [Wether or not to collect nfs statistics])
+fi
+AM_CONDITIONAL(BUILD_MODULE_NFS, test "x$enable_nfs" = "xyes")
+
+AC_ARG_ENABLE(ping, AC_HELP_STRING([--disable-ping], [Disable ping statistics]),, [enable_ping="yes"])
+if test "x$enable_ping" != "xno"
+then
+ enable_ping="yes"
+fi
+if test "x$enable_ping" = "xno"
+then
+ AC_DEFINE(COLLECT_PING, 0, [Wether or not to collect ping statistics])
+fi
+AM_CONDITIONAL(BUILD_MODULE_PING, test "x$enable_ping" = "xyes")
+
+AC_ARG_ENABLE(processes, AC_HELP_STRING([--disable-processes], [Disable processes statistics]),, [enable_processes="yes"])
+if test "x$enable_processes" != "xno"
+then
+ if test "x$ac_system" = "xLinux"
+ then
+ enable_processes="yes"
+ else
+ enable_processes="no"
+ fi
+fi
+if test "x$enable_processes" = "xno"
+then
+ AC_DEFINE(COLLECT_PROCESSES, 0, [Wether or not to collect processes statistics])
+fi
+AM_CONDITIONAL(BUILD_MODULE_PROCESSES, test "x$enable_processes" = "xyes")
+
+AC_ARG_ENABLE(sensors, AC_HELP_STRING([--disable-sensors], [Disable lm_sensors statistics]),, [enable_sensors=$with_lm_sensors])
+if test "x$enable_sensors" != "xno"
+then
+ if test "x$with_lm_sensors" = "xyes"
+ then
+ enable_sensors="yes"
+ else
+ enable_sensors="no"
+ fi
+fi
+if test "x$enable_sensors" = "xno"
+then
+ AC_DEFINE(COLLECT_SENSORS, 0, [Wether or not to collect lm_sensors statistics])
+fi
+AM_CONDITIONAL(BUILD_MODULE_SENSORS, test "x$enable_sensors" = "xyes")
+
+AC_ARG_ENABLE(serial, AC_HELP_STRING([--disable-serial], [Disable serial statistics]),, [enable_serial="yes"])
+if test "x$enable_serial" != "xno"
+then
+ if test "x$ac_system" = "xLinux"
+ then
+ enable_serial="yes"
+ else
+ enable_serial="no"
+ fi
+fi
+if test "x$enable_serial" = "xno"
+then
+ AC_DEFINE(COLLECT_SERIAL, 0, [Wether or not to collect serial statistics])
+fi
+AM_CONDITIONAL(BUILD_MODULE_SERIAL, test "x$enable_serial" = "xyes")
+
+AC_ARG_ENABLE(swap, AC_HELP_STRING([--disable-swap], [Disable swap statistics]),, [enable_swap="yes"])
+if test "x$enable_swap" != "xno"
+then
+ if test "x$ac_system" = "xLinux" -o "x$with_kstat" = "xyes" -o "x$with_libstatgrab" = "xyes"
+ then
+ enable_swap="yes"
+ else
+ enable_swap="no"
+ fi
+fi
+if test "x$enable_swap" = "xno"
+then
+ AC_DEFINE(COLLECT_SWAP, 0, [Wether or not to collect swap statistics])
+fi
+AM_CONDITIONAL(BUILD_MODULE_SWAP, test "x$enable_swap" = "xyes")
+
+AC_ARG_ENABLE(tape, AC_HELP_STRING([--disable-tape], [Disable tape statistics]),, [enable_tape="yes"])
+if test "x$enable_tape" != "xno"
+then
+ if test "x$with_kstat" = "xyes"
+ then
+ enable_tape="yes"
+ else
+ enable_tape="no"
+ fi
+fi
+if test "x$enable_tape" = "xno"
+then
+ AC_DEFINE(COLLECT_TAPE, 0, [Wether or not to collect tape statistics])
+fi
+AM_CONDITIONAL(BUILD_MODULE_TAPE, test "x$enable_tape" = "xyes")
+
+AC_ARG_ENABLE(traffic, AC_HELP_STRING([--disable-traffic], [Disable system traffic statistics]),, [enable_traffic="yes"])
+if test "x$enable_traffic" != "xno"
+then
+ if test "x$ac_system" = "xLinux" -o "x$with_kstat" = "xyes" -o "x$with_libstatgrab" = "xyes"
+ then
+ enable_traffic="yes"
+ else
+ enable_traffic="no"
+ fi
+fi
+if test "x$enable_traffic" = "xno"
+then
+ AC_DEFINE(COLLECT_TRAFFIC, 0, [Wether or not to collect network traffic statistics])
+fi
+AM_CONDITIONAL(BUILD_MODULE_TRAFFIC, test "x$enable_traffic" = "xyes")
+
+AC_OUTPUT(Makefile src/libping/Makefile src/Makefile)
+
+cat <<EOF;
+
+Configuration:
+ Libraries:
+ librrd . . . . . . $with_rrdtool
+ lm_sensors . . . . $with_lm_sensors
+ libstatgrab . . . . $with_libstatgrab
+ libkstat . . . . . $with_kstat
+
+ Features:
+ cpu . . . . . . . . $enable_cpu
+ cpufreq . . . . . . $enable_cpufreq
+ disk . . . . . . . $enable_disk
+ quota . . . . . . . $enable_quota
+ hddtemp . . . . . . $enable_hddtemp
+ load . . . . . . . $enable_load
+ memory . . . . . . $enable_memory
+ nfs . . . . . . . . $enable_nfs
+ ping . . . . . . . $enable_ping
+ processes . . . . . $enable_processes
+ sensors . . . . . . $enable_sensors
+ serial . . . . . . $enable_serial
+ swap . . . . . . . $enable_swap
+ tape . . . . . . . $enable_tape
+ traffic . . . . . . $enable_traffic
+
+EOF
--- /dev/null
+if BUILD_MODULE_PING
+SUBDIRS = libping
+endif
+
+sbin_PROGRAMS = collectd
+
+collectd_SOURCES = collectd.c collectd.h \
+ common.c common.h \
+ multicast.c multicast.h \
+ plugin.c plugin.h
+collectd_CFLAGS = -DPLUGINDIR='"$(pkglibdir)"'
+collectd_LDFLAGS = -dlopen self
+if BUILD_WITH_RRDTOOL
+collectd_LDFLAGS += -lrrd
+endif
+
+pkglib_LTLIBRARIES =
+
+if BUILD_MODULE_CPU
+pkglib_LTLIBRARIES += cpu.la
+cpu_la_SOURCES = cpu.c cpu.h
+cpu_la_LDFLAGS = -module
+endif
+
+if BUILD_MODULE_CPUFREQ
+pkglib_LTLIBRARIES += cpufreq.la
+cpufreq_la_SOURCES = cpufreq.c cpufreq.h
+cpufreq_la_LDFLAGS = -module
+endif
+
+if BUILD_MODULE_DISK
+pkglib_LTLIBRARIES += disk.la
+disk_la_SOURCES = disk.c disk.h
+disk_la_LDFLAGS = -module
+endif
+
+if BUILD_MODULE_QUOTA
+pkglib_LTLIBRARIES += quota.la
+quota_la_SOURCES = quota_plugin.c quota_plugin.h
+quota_la_SOURCES += quota_debug.c quota_debug.h
+quota_la_SOURCES += quota_mnt.c quota_mnt.h quota_mntopt.h
+quota_la_SOURCES += quota_fs.c quota_fs.h
+quota_la_LDFLAGS = -module
+quota_la_CFLAGS = -Werror
+endif
+
+if BUILD_MODULE_HDDTEMP
+pkglib_LTLIBRARIES += hddtemp.la
+hddtemp_la_SOURCES = hddtemp.c hddtemp.h
+hddtemp_la_LDFLAGS = -module
+endif
+
+if BUILD_MODULE_LOAD
+pkglib_LTLIBRARIES += load.la
+load_la_SOURCES = load.c load.h
+load_la_LDFLAGS = -module
+endif
+
+if BUILD_MODULE_MEMORY
+pkglib_LTLIBRARIES += memory.la
+memory_la_SOURCES = memory.c memory.h
+memory_la_LDFLAGS = -module
+endif
+
+if BUILD_MODULE_NFS
+pkglib_LTLIBRARIES += nfs.la
+nfs_la_SOURCES = nfs.c nfs.h
+nfs_la_LDFLAGS = -module
+endif
+
+if BUILD_MODULE_PING
+pkglib_LTLIBRARIES += ping.la
+ping_la_SOURCES = ping.c ping.h
+ping_la_LDFLAGS = -module
+ping_la_LIBADD = libping/libping.la
+ping_la_DEPENDENCIES = libping/libping.la
+endif
+
+if BUILD_MODULE_PROCESSES
+pkglib_LTLIBRARIES += processes.la
+processes_la_SOURCES = processes.c processes.h
+processes_la_LDFLAGS = -module
+endif
+
+if BUILD_MODULE_SENSORS
+pkglib_LTLIBRARIES += sensors.la
+sensors_la_SOURCES = sensors.c sensors.h
+sensors_la_LDFLAGS = -module -lsensors
+endif
+
+if BUILD_MODULE_SERIAL
+pkglib_LTLIBRARIES += serial.la
+serial_la_SOURCES = serial.c serial.h
+serial_la_LDFLAGS = -module
+endif
+
+if BUILD_MODULE_SWAP
+pkglib_LTLIBRARIES += swap.la
+swap_la_SOURCES = swap.c swap.h
+swap_la_LDFLAGS = -module
+endif
+
+if BUILD_MODULE_TAPE
+pkglib_LTLIBRARIES += tape.la
+tape_la_SOURCES = tape.c tape.h
+tape_la_LDFLAGS = -module
+endif
+
+if BUILD_MODULE_TRAFFIC
+pkglib_LTLIBRARIES += traffic.la
+traffic_la_SOURCES = traffic.c traffic.h
+traffic_la_LDFLAGS = -module
+endif
+
+man_MANS = collectd.1
+#collectd_1_SOURCES = collectd.pod
+
+EXTRA_DIST = $(man_MANS)
+
+.pod.1:
+ pod2man --release=$(VERSION) --center=$(PACKAGE) $< >$@
--- /dev/null
+#ifndef COLLECTD_H
+#define COLLECTD_H
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <string.h>
+#include <sys/wait.h>
+#include <signal.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
+#include <syslog.h>
+#include <limits.h>
+#include <time.h>
+
+#include "config.h"
+
+#ifndef HAVE_RRD_H
+#undef HAVE_LIBRRD
+#endif
+
+#ifdef HAVE_LIBRRD
+#include <rrd.h>
+#endif /* HAVE_LIBRRD */
+
+/* Won't work without the header file */
+#ifndef HAVE_KSTAT_H
+#undef HAVE_LIBKSTAT
+#endif
+
+#ifdef HAVE_LIBKSTAT
+#include <kstat.h>
+#include <sys/param.h>
+#endif /* HAVE_LIBKSTAT */
+
+/* Won't work without the header file */
+#ifndef HAVE_STATGRAB_H
+#undef HAVE_LIBSTATGRAB
+#endif
+
+#ifdef HAVE_LIBSTATGRAB
+#include <statgrab.h>
+#endif
+
+#ifndef DEBUG
+#define DEBUG 0
+#endif
+
+#ifndef PLUGINDIR
+#define PLUGINDIR "/usr/lib/collectd"
+#endif
+
+#define MODE_SERVER 0x01
+#define MODE_CLIENT 0x02
+#define MODE_LOCAL 0x03
+
+extern time_t curtime;
+extern int operating_mode;
+
+#endif /* COLLECTD_H */
--- /dev/null
+/* src/config.h.in. Generated from configure.in by autoheader. */
+
+/* Wether or not to collect CPU usage statistics */
+#undef COLLECT_CPU
+
+/* Wether or not to collect cpu frequency statistics */
+#undef COLLECT_CPUFREQ
+
+/* Wether or not to collect diskstats */
+#undef COLLECT_DISK
+
+/* Wether or not to collect hdd temperature statistics */
+#undef COLLECT_HDDTEMP
+
+/* Wether or not to collect system load statistics */
+#undef COLLECT_LOAD
+
+/* Wether or not to collect memory statistics */
+#undef COLLECT_MEMORY
+
+/* Wether or not to collect nfs statistics */
+#undef COLLECT_NFS
+
+/* Wether or not to collect ping statistics */
+#undef COLLECT_PING
+
+/* Wether or not to collect processes statistics */
+#undef COLLECT_PROCESSES
+
+/* Wether or not to collect quotastats */
+#undef COLLECT_QUOTA
+
+/* Wether or not to collect lm_sensors statistics */
+#undef COLLECT_SENSORS
+
+/* Wether or not to collect serial statistics */
+#undef COLLECT_SERIAL
+
+/* Wether or not to collect swap statistics */
+#undef COLLECT_SWAP
+
+/* Wether or not to collect tape statistics */
+#undef COLLECT_TAPE
+
+/* Wether or not to collect network traffic statistics */
+#undef COLLECT_TRAFFIC
+
+/* Define to 1 if you have the <arpa/inet.h> header file. */
+#undef HAVE_ARPA_INET_H
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#undef HAVE_DLFCN_H
+
+/* Define to 1 if you have the <errno.h> header file. */
+#undef HAVE_ERRNO_H
+
+/* Define to 1 if you have the <fcntl.h> header file. */
+#undef HAVE_FCNTL_H
+
+/* Define to 1 if you have the `getfsent' function. */
+#undef HAVE_GETFSENT
+
+/* Define to 1 if you have the `gethostbyname' function. */
+#undef HAVE_GETHOSTBYNAME
+
+/* Define to 1 if you have the `getmntent' function. */
+#undef HAVE_GETMNTENT
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#undef HAVE_GETTIMEOFDAY
+
+/* Define to 1 if you have the `getvfsent' function. */
+#undef HAVE_GETVFSENT
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#undef HAVE_INTTYPES_H
+
+/* Define to 1 if you have the <kstat.h> header file. */
+#undef HAVE_KSTAT_H
+
+/* Define to 1 if you have the `devinfo' library (-ldevinfo). */
+#undef HAVE_LIBDEVINFO
+
+/* Define to 1 if you have the `dl' library (-ldl). */
+#undef HAVE_LIBDL
+
+/* Define to 1 if you have the `kstat' library (-lkstat). */
+#undef HAVE_LIBKSTAT
+
+/* Define to 1 if you have the `m' library (-lm). */
+#undef HAVE_LIBM
+
+/* Define to 1 if you have the `nsl' library (-lnsl). */
+#undef HAVE_LIBNSL
+
+/* Define to 1 if you have the `resolv' library (-lresolv). */
+#undef HAVE_LIBRESOLV
+
+/* Define to 1 if you have the `rrd' library (-lrrd). */
+#undef HAVE_LIBRRD
+
+/* Define to 1 if you have the sensors library (-lsensors). */
+#undef HAVE_LIBSENSORS
+
+/* Define to 1 if you have the `socket' library (-lsocket). */
+#undef HAVE_LIBSOCKET
+
+/* Define to 1 if you have the `statgrab' library (-lstatgrab). */
+#undef HAVE_LIBSTATGRAB
+
+/* Define to 1 if you have the `listmntent' function. */
+#undef HAVE_LISTMNTENT
+
+/* Define to 1 if you have the `memcpy' function. */
+#undef HAVE_MEMCPY
+
+/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_MEMORY_H
+
+/* Define to 1 if you have the <mntent.h> header file. */
+#undef HAVE_MNTENT_H
+
+/* Define to 1 if you have the <netdb.h> header file. */
+#undef HAVE_NETDB_H
+
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#undef HAVE_NETINET_IN_H
+
+/* Define to 1 if you have the <paths.h> header file. */
+#undef HAVE_PATHS_H
+
+/* Define to 1 if you have the <rrd.h> header file. */
+#undef HAVE_RRD_H
+
+/* Define to 1 if you have the `select' function. */
+#undef HAVE_SELECT
+
+/* Define to 1 if you have the <sensors/sensors.h> header file. */
+#undef HAVE_SENSORS_SENSORS_H
+
+/* Define to 1 if you have the <signal.h> header file. */
+#undef HAVE_SIGNAL_H
+
+/* Define to 1 if you have the `socket' function. */
+#undef HAVE_SOCKET
+
+/* Define to 1 if you have the <statgrab.h> header file. */
+#undef HAVE_STATGRAB_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#undef HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#undef HAVE_STDLIB_H
+
+/* Define to 1 if you have the `strcasecmp' function. */
+#undef HAVE_STRCASECMP
+
+/* Define to 1 if you have the `strchr' function. */
+#undef HAVE_STRCHR
+
+/* Define to 1 if you have the `strcmp' function. */
+#undef HAVE_STRCMP
+
+/* Define to 1 if you have the `strdup' function. */
+#undef HAVE_STRDUP
+
+/* Define to 1 if you have the <strings.h> header file. */
+#undef HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#undef HAVE_STRING_H
+
+/* Define to 1 if you have the `strlen' function. */
+#undef HAVE_STRLEN
+
+/* Define to 1 if you have the `strncasecmp' function. */
+#undef HAVE_STRNCASECMP
+
+/* Define to 1 if you have the `strncmp' function. */
+#undef HAVE_STRNCMP
+
+/* Define to 1 if you have the `strncpy' function. */
+#undef HAVE_STRNCPY
+
+/* Define to 1 if you have the `strstr' function. */
+#undef HAVE_STRSTR
+
+/* Define to 1 if you have the `strtol' function. */
+#undef HAVE_STRTOL
+
+/* Define to 1 if you have the <syslog.h> header file. */
+#undef HAVE_SYSLOG_H
+
+/* Define to 1 if you have the <sys/fs_types.h> header file. */
+#undef HAVE_SYS_FS_TYPES_H
+
+/* Define to 1 if you have the <sys/mnttab.h> header file. */
+#undef HAVE_SYS_MNTTAB_H
+
+/* Define to 1 if you have the <sys/mount.h> header file. */
+#undef HAVE_SYS_MOUNT_H
+
+/* Define to 1 if you have the <sys/resource.h> header file. */
+#undef HAVE_SYS_RESOURCE_H
+
+/* Define to 1 if you have the <sys/select.h> header file. */
+#undef HAVE_SYS_SELECT_H
+
+/* Define to 1 if you have the <sys/socket.h> header file. */
+#undef HAVE_SYS_SOCKET_H
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#undef HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/times.h> header file. */
+#undef HAVE_SYS_TIMES_H
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#undef HAVE_SYS_TIME_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#undef HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <sys/vfstab.h> header file. */
+#undef HAVE_SYS_VFSTAB_H
+
+/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
+#undef HAVE_SYS_WAIT_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#undef HAVE_UNISTD_H
+
+/* Define to 1 if you have the <xfs/xqm.h> header file. */
+#undef HAVE_XFS_XQM_H
+
+/* True if program is to be compiled for a Linux kernel */
+#undef KERNEL_LINUX
+
+/* True if program is to be compiled for a Solaris kernel */
+#undef KERNEL_SOLARIS
+
+/* Name of package */
+#undef PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#undef PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#undef PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#undef PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#undef PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#undef PACKAGE_VERSION
+
+/* Define to 1 if you have the ANSI C header files. */
+#undef STDC_HEADERS
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#undef TIME_WITH_SYS_TIME
+
+/* Version number of package */
+#undef VERSION
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#undef const
+
+/* Define to `int' if <sys/types.h> does not define. */
+#undef pid_t
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#undef size_t
--- /dev/null
+/**
+ * collectd - src/quota_plugin.c
+ * Copyright (C) 2005 Niki W. Waibel
+ *
+ * This program is free software; you can redistribute it and/
+ * or modify it under the terms of the GNU General Public Li-
+ * cence as published by the Free Software Foundation; either
+ * version 2 of the Licence, or any later version.
+ *
+ * This program is distributed in the hope that it will be use-
+ * ful, but WITHOUT ANY WARRANTY; without even the implied war-
+ * ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public Licence for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * Licence along with this program; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
+ * USA.
+ *
+ * Author:
+ * Niki W. Waibel <niki.waibel@gmx.net>
+**/
+
+#include "common.h"
+#include "quota_debug.h"
+
+/* *** *** *** global variables *** *** *** */
+#if QUOTA_PLUGIN_DEBUG
+ FILE *QUOTA_DBG_FILE = NULL;
+#endif
+
--- /dev/null
+/**
+ * collectd - src/quota_debug.h
+ * Copyright (C) 2005 Niki W. Waibel
+ *
+ * This program is free software; you can redistribute it and/
+ * or modify it under the terms of the GNU General Public Li-
+ * cence as published by the Free Software Foundation; either
+ * version 2 of the Licence, or any later version.
+ *
+ * This program is distributed in the hope that it will be use-
+ * ful, but WITHOUT ANY WARRANTY; without even the implied war-
+ * ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public Licence for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * Licence along with this program; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
+ * USA.
+ *
+ * Author:
+ * Niki W. Waibel <niki.waibel@gmx.net>
+**/
+
+#if !COLLECTD_QUOTA_DEBUG_H
+#define COLLECTD_QUOTA_DEBUG_H 1
+
+#include "common.h"
+
+#define QUOTA_PLUGIN_DEBUG 1
+
+#if QUOTA_PLUGIN_DEBUG
+ #include <stdio.h>
+ extern FILE *QUOTA_DBG_FILE;
+ #define DBG(...) \
+ { \
+ if(QUOTA_DBG_FILE != NULL) { \
+ fprintf(QUOTA_DBG_FILE, "%s:%d:%s(): ", \
+ __FILE__, __LINE__, __func__); \
+ fprintf(QUOTA_DBG_FILE, __VA_ARGS__); \
+ fprintf(QUOTA_DBG_FILE, "\n"); \
+ fflush(QUOTA_DBG_FILE); \
+ } \
+ }
+ #define DBG_INIT(...) \
+ { \
+ QUOTA_DBG_FILE = fopen("collectd.log", "a"); \
+ if(QUOTA_DBG_FILE == NULL) { \
+ /* stderr is redirected to /dev/null, so you \
+ will not see anything */ \
+ fprintf(stderr, "Cannot open quota debug file.\n"); \
+ } else { \
+ DBG(__VA_ARGS__); \
+ } \
+ }
+#else /* !QUOTA_PLUGIN_DEBUG */
+ #define DBG(...) /**/
+ #define DBG_INIT(...) /**/
+#endif /* QUOTA_PLUGIN_DEBUG */
+
+#endif /* !COLLECTD_QUOTA_DEBUG_H */
+
--- /dev/null
+/**
+ * collectd - src/quota_fs.c
+ * Copyright (C) 2005 Niki W. Waibel
+ *
+ * This program is free software; you can redistribute it and/
+ * or modify it under the terms of the GNU General Public Li-
+ * cence as published by the Free Software Foundation; either
+ * version 2 of the Licence, or any later version.
+ *
+ * This program is distributed in the hope that it will be use-
+ * ful, but WITHOUT ANY WARRANTY; without even the implied war-
+ * ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public Licence for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * Licence along with this program; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
+ * USA.
+ *
+ * Author:
+ * Niki W. Waibel <niki.waibel@gmx.net>
+**/
+
+#include "common.h"
+#include "quota_debug.h"
+#include "quota_fs.h"
+
+int
+quota_fs_issupported(const char *fsname)
+{
+ if(!strcmp(fsname, "ext2")
+ || !strcmp(fsname, "ext3")
+ || !strcmp(fsname, "ufs")
+ || !strcmp(fsname, "vxfs")
+ || !strcmp(fsname, "zfs"))
+ {
+ return EXIT_SUCCESS;
+ } else {
+#if 0
+ DBG("%s filesystem not supported", fsname);
+#endif
+ return EXIT_FAILURE;
+ }
+}
+
+int
+quota_fs_isnfs(const char *fsname)
+{
+ if(!strcmp(fsname, "nfs") || !strcmp(fsname, "nfs4")) {
+ return EXIT_SUCCESS;
+ } else {
+ return EXIT_FAILURE;
+ }
+}
--- /dev/null
+/**
+ * collectd - src/quota_fs.h
+ * Copyright (C) 2005 Niki W. Waibel
+ *
+ * This program is free software; you can redistribute it and/
+ * or modify it under the terms of the GNU General Public Li-
+ * cence as published by the Free Software Foundation; either
+ * version 2 of the Licence, or any later version.
+ *
+ * This program is distributed in the hope that it will be use-
+ * ful, but WITHOUT ANY WARRANTY; without even the implied war-
+ * ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public Licence for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * Licence along with this program; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
+ * USA.
+ *
+ * Author:
+ * Niki W. Waibel <niki.waibel@gmx.net>
+**/
+
+#if !COLLECTD_QUOTA_FS_H
+#define COLLECTD_QUOTA_FS_H 1
+
+#include "common.h"
+
+int quota_fs_issupported(const char *fsname);
+int quota_fs_isnfs(const char *fsname);
+
+#endif /* !COLLECTD_QUOTA_FS_H */
+
--- /dev/null
+/**
+ * collectd - src/quota_mnt.c
+ * Copyright (C) 2005 Niki W. Waibel
+ *
+ * This program is free software; you can redistribute it and/
+ * or modify it under the terms of the GNU General Public Li-
+ * cence as published by the Free Software Foundation; either
+ * version 2 of the Licence, or any later version.
+ *
+ * This program is distributed in the hope that it will be use-
+ * ful, but WITHOUT ANY WARRANTY; without even the implied war-
+ * ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public Licence for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * Licence along with this program; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
+ * USA.
+ *
+ * Author:
+ * Niki W. Waibel <niki.waibel@gmx.net>
+**/
+
+#include "common.h"
+#include "quota_debug.h"
+#include "quota_fs.h"
+#include "quota_mnt.h"
+
+#include <ctype.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#if HAVE_MNTENT_H /* 4.3BSD, SunOS, HP-UX, Dynix, Irix. */
+#include <mntent.h>
+#endif
+#if HAVE_MNTTAB_H /* SVR2, SVR3. */
+#include <mnttab.h>
+#endif
+#if HAVE_PATHS_H
+#include <paths.h>
+#endif
+#include <stdlib.h>
+#include <string.h>
+#if HAVE_SYS_FS_TYPES_H /* Ultrix. */
+#include <sys/fs_types.h>
+#endif
+#if HAVE_SYS_MNTTAB_H /* SVR4. */
+#include <sys/mnttab.h>
+#endif
+#if HAVE_SYS_MOUNT_H /* 4.4BSD, Ultrix. */
+#include <sys/mount.h>
+#endif
+#if HAVE_SYS_VFSTAB_H
+#include <sys/vfstab.h>
+#endif
+#include <sys/quota.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/vfs.h>
+#if HAVE_XFS_XQM_H
+#include <xfs/xqm.h>
+#define xfs_mem_dqinfo fs_quota_stat
+#define Q_XFS_GETQSTAT Q_XGETQSTAT
+#define XFS_SUPER_MAGIC_STR "XFSB"
+#define XFS_SUPER_MAGIC2_STR "BSFX"
+#endif
+
+#include "quota_mntopt.h"
+
+/* *** *** *** local functions *** *** *** */
+
+/* stolen from quota-3.13 (quota-tools) */
+
+#define PROC_PARTITIONS "/proc/partitions"
+#define DEVLABELDIR "/dev"
+#define UUID 1
+#define VOL 2
+
+#define AUTOFS_DIR_MAX 64 /* Maximum number of autofs directories */
+
+static struct uuidCache_s {
+ struct uuidCache_s *next;
+ char uuid[16];
+ char *label;
+ char *device;
+} *uuidCache = NULL;
+
+#define EXT2_SUPER_MAGIC 0xEF53
+struct ext2_super_block {
+ unsigned char s_dummy1[56];
+ unsigned char s_magic[2];
+ unsigned char s_dummy2[46];
+ unsigned char s_uuid[16];
+ char s_volume_name[16];
+};
+#define ext2magic(s) ((unsigned int)s.s_magic[0] \
+ + (((unsigned int)s.s_magic[1]) << 8))
+
+#if HAVE_XFS_XQM_H
+struct xfs_super_block {
+ unsigned char s_magic[4];
+ unsigned char s_dummy[28];
+ unsigned char s_uuid[16];
+ unsigned char s_dummy2[60];
+ char s_fsname[12];
+};
+#endif /* HAVE_XFS_XQM_H */
+
+#define REISER_SUPER_MAGIC "ReIsEr2Fs"
+struct reiserfs_super_block {
+ unsigned char s_dummy1[52];
+ unsigned char s_magic[10];
+ unsigned char s_dummy2[22];
+ unsigned char s_uuid[16];
+ char s_volume_name[16];
+};
+
+void
+sstrncpy(char *d, const char *s, int len)
+{
+ strncpy(d, s, len);
+ d[len - 1] = 0;
+}
+
+char *
+sstrdup(const char *s)
+{
+ char *r = strdup(s);
+ if(r == NULL) {
+ DBG("Not enough memory.");
+ exit(3);
+ }
+ return r;
+}
+
+void *
+smalloc(size_t size)
+{
+ void *ret = malloc(size);
+ if(ret == NULL) {
+ DBG("Not enough memory.");
+ exit(3);
+ }
+ return ret;
+}
+
+/* for now, only ext2 and xfs are supported */
+static int
+get_label_uuid(const char *device, char **label, char *uuid)
+{
+ /* start with ext2 and xfs tests, taken from mount_guess_fstype */
+ /* should merge these later */
+ int fd, rv = 1;
+ size_t namesize;
+ struct ext2_super_block e2sb;
+ struct xfs_super_block xfsb;
+ struct reiserfs_super_block reisersb;
+
+ fd = open(device, O_RDONLY);
+ if(fd == -1) {
+ return rv;
+ }
+
+ if(lseek(fd, 1024, SEEK_SET) == 1024
+ && read(fd, (char *)&e2sb, sizeof(e2sb)) == sizeof(e2sb)
+ && ext2magic(e2sb) == EXT2_SUPER_MAGIC) {
+ memcpy(uuid, e2sb.s_uuid, sizeof(e2sb.s_uuid));
+ namesize = sizeof(e2sb.s_volume_name);
+ *label = smalloc(namesize + 1);
+ sstrncpy(*label, e2sb.s_volume_name, namesize);
+ rv = 0;
+#if HAVE_XFS_XQM_H
+ } else if(lseek(fd, 0, SEEK_SET) == 0
+ && read(fd, (char *)&xfsb, sizeof(xfsb)) == sizeof(xfsb)
+ && (strncmp((char *)&xfsb.s_magic, XFS_SUPER_MAGIC_STR, 4) == 0 ||
+ strncmp((char *)&xfsb.s_magic, XFS_SUPER_MAGIC2_STR, 4) == 0)) {
+ memcpy(uuid, xfsb.s_uuid, sizeof(xfsb.s_uuid));
+ namesize = sizeof(xfsb.s_fsname);
+ *label = smalloc(namesize + 1);
+ sstrncpy(*label, xfsb.s_fsname, namesize);
+ rv = 0;
+#endif /* HAVE_XFS_XQM_H */
+ } else if(lseek(fd, 65536, SEEK_SET) == 65536
+ && read(fd, (char *)&reisersb, sizeof(reisersb)) == sizeof(reisersb)
+ && !strncmp((char *)&reisersb.s_magic, REISER_SUPER_MAGIC, 9)) {
+ memcpy(uuid, reisersb.s_uuid, sizeof(reisersb.s_uuid));
+ namesize = sizeof(reisersb.s_volume_name);
+ *label = smalloc(namesize + 1);
+ sstrncpy(*label, reisersb.s_volume_name, namesize);
+ rv = 0;
+ }
+ close(fd);
+ return rv;
+}
+
+static void
+uuidcache_addentry(char *device, char *label, char *uuid)
+{
+ struct uuidCache_s *last;
+
+ if(!uuidCache) {
+ last = uuidCache = smalloc(sizeof(*uuidCache));
+ } else {
+ for(last = uuidCache; last->next; last = last->next);
+ last->next = smalloc(sizeof(*uuidCache));
+ last = last->next;
+ }
+ last->next = NULL;
+ last->device = device;
+ last->label = label;
+ memcpy(last->uuid, uuid, sizeof(last->uuid));
+}
+
+static void
+uuidcache_init(void)
+{
+ char line[100];
+ char *s;
+ int ma, mi, sz;
+ static char ptname[100];
+ FILE *procpt;
+ char uuid[16], *label = NULL;
+ char device[110];
+ int firstPass;
+ int handleOnFirst;
+
+ if(uuidCache) {
+ return;
+ }
+
+ procpt = fopen(PROC_PARTITIONS, "r");
+ if(procpt == NULL) {
+ return;
+ }
+
+ for(firstPass = 1; firstPass >= 0; firstPass--) {
+ fseek(procpt, 0, SEEK_SET);
+ while(fgets(line, sizeof(line), procpt)) {
+ if(sscanf(line, " %d %d %d %[^\n ]",
+ &ma, &mi, &sz, ptname) != 4)
+ {
+ continue;
+ }
+
+ /* skip extended partitions (heuristic: size 1) */
+ if(sz == 1) {
+ continue;
+ }
+
+ /* look only at md devices on first pass */
+ handleOnFirst = !strncmp(ptname, "md", 2);
+ if(firstPass != handleOnFirst) {
+ continue;
+ }
+
+ /* skip entire disk (minor 0, 64, ... on ide;
+ 0, 16, ... on sd) */
+ /* heuristic: partition name ends in a digit */
+
+ for(s = ptname; *s; s++);
+
+ if(isdigit(s[-1])) {
+ /*
+ * Note: this is a heuristic only - there is no reason
+ * why these devices should live in /dev.
+ * Perhaps this directory should be specifiable by option.
+ * One might for example have /devlabel with links to /dev
+ * for the devices that may be accessed in this way.
+ * (This is useful, if the cdrom on /dev/hdc must not
+ * be accessed.)
+ */
+ snprintf(device, sizeof(device), "%s/%s",
+ DEVLABELDIR, ptname);
+ if(!get_label_uuid(device, &label, uuid)) {
+ uuidcache_addentry(sstrdup(device),
+ label, uuid);
+ }
+ }
+ }
+ }
+ fclose(procpt);
+}
+
+static unsigned char
+fromhex(char c)
+{
+ if(isdigit(c)) {
+ return (c - '0');
+ } else if(islower(c)) {
+ return (c - 'a' + 10);
+ } else {
+ return (c - 'A' + 10);
+ }
+}
+
+static char *
+get_spec_by_x(int n, const char *t)
+{
+ struct uuidCache_s *uc;
+
+ uuidcache_init();
+ uc = uuidCache;
+
+ while(uc) {
+ switch(n) {
+ case UUID:
+ if(!memcmp(t, uc->uuid, sizeof(uc->uuid))) {
+ return sstrdup(uc->device);
+ }
+ break;
+ case VOL:
+ if(!strcmp(t, uc->label)) {
+ return sstrdup(uc->device);
+ }
+ break;
+ }
+ uc = uc->next;
+ }
+ return NULL;
+}
+
+static char *
+get_spec_by_uuid(const char *s)
+{
+ char uuid[16];
+ int i;
+
+ if(strlen(s) != 36
+ || s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-') {
+ goto bad_uuid;
+ }
+
+ for(i=0; i<16; i++) {
+ if(*s == '-') {
+ s++;
+ }
+ if(!isxdigit(s[0]) || !isxdigit(s[1])) {
+ goto bad_uuid;
+ }
+ uuid[i] = ((fromhex(s[0]) << 4) | fromhex(s[1]));
+ s += 2;
+ }
+ return get_spec_by_x(UUID, uuid);
+
+ bad_uuid:
+ DBG("Found an invalid UUID: %s", s);
+ return NULL;
+}
+
+static char *
+get_spec_by_volume_label(const char *s)
+{
+ return get_spec_by_x(VOL, s);
+}
+
+const char *
+get_device_name(const char *item)
+{
+ const char *rc;
+
+ if(!strncmp(item, "UUID=", 5)) {
+ DBG("TODO: check UUID= code!");
+ rc = get_spec_by_uuid(item + 5);
+ } else if(!strncmp(item, "LABEL=", 6)) {
+ DBG("TODO: check LABEL= code!");
+ rc = get_spec_by_volume_label(item + 6);
+ } else {
+ rc = sstrdup(item);
+ }
+ if(!rc) {
+ DBG("Error checking device name: %s", item);
+ }
+ return rc;
+}
+
+/* Return if given option has nonempty argument */
+char *
+hasmntoptarg(struct mntent *mnt, char *opt)
+{
+ char *p = hasmntopt(mnt, opt);
+
+ if(!p) {
+ return NULL;
+ }
+ p += strlen(opt);
+ if(*p == '=' && p[1] != ',') {
+ return p+1;
+ }
+ return NULL;
+}
+
+/*
+ * Check whether give filesystem type is supported
+ */
+static int
+correct_fstype(char *type)
+{
+ char *mtype = sstrdup(type), *next;
+
+ type = mtype;
+ do {
+ next = strchr(type, ',');
+ if(next) {
+ *next = 0;
+ }
+ if(!strcmp(type, MNTTYPE_EXT2)
+ || !strcmp(type, MNTTYPE_EXT3)
+ || !strcmp(type, MNTTYPE_JFS)
+ || !strcmp(type, MNTTYPE_MINIX)
+ || !strcmp(type, MNTTYPE_UFS)
+ || !strcmp(type, MNTTYPE_UDF)
+ || !strcmp(type, MNTTYPE_REISER)
+ || !strcmp(type, MNTTYPE_XFS)
+ || !strcmp(type, MNTTYPE_NFS)
+ || !strcmp(type, MNTTYPE_NFS4))
+ {
+ free(mtype);
+ return 1;
+ }
+ type = next+1;
+ } while(next);
+ free(mtype);
+ return 0;
+}
+
+/*
+ * Check for various kinds of NFS filesystem
+ */
+int
+nfs_fstype(char *type)
+{
+ return !strcmp(type, MNTTYPE_NFS) || !strcmp(type, MNTTYPE_NFS4);
+}
+
+#if HAVE_XFS_XQM_H
+/*
+ * Check for XFS filesystem with quota accounting enabled
+ */
+static int hasxfsquota(struct mntent *mnt, int type)
+{
+ int ret = 0;
+ u_int16_t sbflags;
+ struct xfs_mem_dqinfo info;
+ const char *dev = get_device_name(mnt->mnt_fsname);
+
+ if(!dev) {
+ return ret;
+ }
+
+ memset(&info, 0, sizeof(struct xfs_mem_dqinfo));
+ if(!quotactl(QCMD(Q_XFS_GETQSTAT, type), dev, 0, (void *)&info)) {
+ sbflags = (info.qs_flags & 0xff00) >> 8;
+ if(type == USRQUOTA && (info.qs_flags & XFS_QUOTA_UDQ_ACCT)) {
+ ret = 1;
+ } else if(type == GRPQUOTA && (info.qs_flags & XFS_QUOTA_GDQ_ACCT)) {
+ ret = 1;
+ }
+ #ifdef XFS_ROOTHACK
+ /*
+ * Old XFS filesystems (up to XFS 1.2 / Linux 2.5.47) had a
+ * hack to allow enabling quota on the root filesystem without
+ * having to specify it at mount time.
+ */
+ else if(strcmp(mnt->mnt_dir, "/")) {
+ ret = 0;
+ } else if(type == USRQUOTA && (sbflags & XFS_QUOTA_UDQ_ACCT)) {
+ ret = 1;
+ } else if(type == GRPQUOTA && (sbflags & XFS_QUOTA_GDQ_ACCT)) {
+ ret = 1;
+ #endif /* XFS_ROOTHACK */
+ }
+ free((char *)dev);
+ return ret;
+}
+#endif /* HAVE_XFS_XQM_H */
+
+/*
+ * Check to see if a particular quota is to be enabled (filesystem mounted
+ * with proper option)
+ */
+int
+hasquota(struct mntent *mnt, int type)
+{
+ if(!correct_fstype(mnt->mnt_type) || hasmntopt(mnt, MNTOPT_NOQUOTA)) {
+ return 0;
+ }
+#if HAVE_XFS_XQM_H
+ if(!strcmp(mnt->mnt_type, MNTTYPE_XFS)) {
+ return hasxfsquota(mnt, type);
+ }
+#endif
+ if(nfs_fstype(mnt->mnt_type)) {
+ /* NFS always has quota or better there is
+ no good way how to detect it */
+ return 1;
+ }
+
+ if((type == USRQUOTA) && (hasmntopt(mnt, MNTOPT_USRQUOTA)
+ || hasmntoptarg(mnt, MNTOPT_USRJQUOTA))) {
+ return 1;
+ }
+ if((type == GRPQUOTA) && (hasmntopt(mnt, MNTOPT_GRPQUOTA)
+ || hasmntoptarg(mnt, MNTOPT_GRPJQUOTA))) {
+ return 1;
+ }
+ if((type == USRQUOTA) && hasmntopt(mnt, MNTOPT_QUOTA)) {
+ return 1;
+ }
+
+ return 0;
+}
+
+/* END stolen from quota-3.13 (quota-tools) */
+
+
+
+#if HAVE_LISTMNTENT
+static void
+quota_mnt_listmntent(struct tabmntent *mntlist, quota_mnt_t **list)
+{
+ struct *p;
+ struct mntent *mnt;
+
+ for(p = mntlist; p; p = p->next) {
+ mnt = p->ment;
+ *list = smalloc(sizeof(quota_mnt_t));
+ list->device = strdup(mnt->mnt_fsname);
+ list->name = strdup(mnt->mnt_dir);
+ list->type = strdup(mnt->mnt_type);
+ list->next = NULL;
+ list = &(ist->next);
+ }
+ freemntlist(mntlist);
+}
+#endif /* HAVE_LISTMNTENT */
+
+
+
+#if HAVE_GETVFSENT
+static void
+quota_mnt_getvfsmnt(FILE *mntf, quota_mnt_t **list)
+{
+ DBG("TODO: getvfsmnt");
+ *list = NULL;
+}
+#endif /* HAVE_GETVFSENT */
+
+
+
+#if HAVE_GETMNTENT
+static void
+quota_mnt_getmntent(FILE *mntf, quota_mnt_t **list)
+{
+ struct mntent *mnt;
+
+ while((mnt = getmntent(mntf)) != NULL) {
+ const char *devname;
+
+#if 0
+ DBG("------------------");
+ DBG("mnt->mnt_fsname %s", mnt->mnt_fsname);
+ DBG("mnt->mnt_dir %s", mnt->mnt_dir);
+ DBG("mnt->mnt_type %s", mnt->mnt_type);
+ DBG("mnt->mnt_opts %s", mnt->mnt_opts);
+ DBG("mnt->mnt_freq %d", mnt->mnt_freq);
+ DBG("mnt->mnt_passno %d", mnt->mnt_passno);
+#endif
+ if(!(devname = get_device_name(mnt->mnt_fsname))) {
+ DBG("can't get devicename for fs (%s) %s (%s): ignored",
+ mnt->mnt_type, mnt->mnt_dir, mnt->mnt_fsname);
+ continue;
+ }
+ if(hasmntopt(mnt, MNTOPT_NOQUOTA) != NULL) {
+ DBG("noquota option on fs (%s) %s (%s): ignored",
+ mnt->mnt_type, mnt->mnt_dir, mnt->mnt_fsname);
+ free((char *)devname);
+ continue;
+ }
+ if(hasmntopt(mnt, MNTOPT_QUOTA) == NULL
+ && hasmntopt(mnt, MNTOPT_USRQUOTA) == NULL
+ && hasmntopt(mnt, MNTOPT_GRPQUOTA) == NULL
+ && quota_fs_isnfs(mnt->mnt_type) == EXIT_FAILURE)
+ {
+ DBG("neither quota/usrquota/grpquota option"
+ " nor nfs fs (%s) %s (%s): ignored",
+ mnt->mnt_type, mnt->mnt_dir, mnt->mnt_fsname);
+ free((char *)devname);
+ continue;
+ }
+ if(quota_fs_issupported(mnt->mnt_type) == EXIT_FAILURE)
+ {
+ DBG("unsupportet fs (%s) %s (%s): ignored",
+ mnt->mnt_type, mnt->mnt_dir, mnt->mnt_fsname);
+ free((char *)devname);
+ continue;
+ }
+#if 0
+ DBG("------------------ OK");
+#endif
+ *list = (quota_mnt_t *)smalloc(sizeof(quota_mnt_t));
+ (*list)->dir = sstrdup(mnt->mnt_dir);
+ (*list)->device = sstrdup(mnt->mnt_fsname);
+ (*list)->opts = QMO_NONE;
+ if(hasmntopt(mnt, MNTOPT_QUOTA) != NULL
+ || hasmntopt(mnt, MNTOPT_USRQUOTA) != NULL) {
+ (*list)->opts |= QMO_USRQUOTA;
+ }
+ if(hasmntopt(mnt, MNTOPT_GRPQUOTA) != NULL) {
+ (*list)->opts |= QMO_GRPQUOTA;
+ }
+ (*list)->next = NULL;
+ list = &((*list)->next);
+ } /* while((mnt = getmntent(mntf)) != NULL) */
+}
+#endif /* HAVE_GETMNTENT */
+
+
+
+quota_mnt_t *
+quota_mnt_getlist(quota_mnt_t **list)
+{
+ /* yes, i know that the indentation is wrong.
+ but show me a better way to do this... */
+ /* see lib/mountlist.c of coreutils for all
+ gory details! */
+#if HAVE_GETMNTENT && defined(_PATH_MOUNTED)
+ {
+ FILE *mntf = NULL;
+ if((mntf = setmntent(_PATH_MOUNTED, "r")) == NULL) {
+ DBG("opening %s failed: %s", _PATH_MOUNTED, strerror(errno));
+#endif
+#if HAVE_GETMNTENT && defined(MNT_MNTTAB)
+ {
+ FILE *mntf = NULL;
+ if((mntf = setmntent(MNT_MNTTAB, "r")) == NULL) {
+ DBG("opening %s failed: %s", MNT_MNTTAB, strerror(errno));
+#endif
+#if HAVE_GETMNTENT && defined(MNTTABNAME)
+ {
+ FILE *mntf = NULL;
+ if((mntf = setmntent(MNTTABNAME, "r")) == NULL) {
+ DBG("opening %s failed: %s", MNTTABNAME, strerror(errno));
+#endif
+#if HAVE_GETMNTENT && defined(_PATH_MNTTAB)
+ {
+ FILE *mntf = NULL;
+ if((mntf = setmntent(_PATH_MNTTAB, "r")) == NULL) {
+ DBG("opening %s failed: %s", _PATH_MNTTAB, strerror(errno));
+#endif
+#if HAVE_GETVFSENT && defined(VFSTAB)
+ {
+ FILE *mntf = NULL;
+ if((mntf = fopen(VFSTAB, "r")) == NULL) {
+ DBG("opening %s failed: %s", VFSTAB, strerror(errno));
+#endif
+#if HAVE_LISTMNTENT
+ {
+ struct tabmntent *mntlist;
+
+ if(listmntent(&mntlist, KMTAB, NULL, NULL) < 0) {
+ DBG("calling listmntent() failed: %s", strerror(errno));
+#endif
+ /* give up */
+ DBG("failed get local mountpoints");
+ *list = NULL;
+ return(NULL);
+
+#if HAVE_LISTMNTENT
+ } else { quota_mnt_listmntent(mntlist, list); }
+ freemntlist(mntlist);
+ }
+#endif
+#if HAVE_GETVFSENT && defined(VFSTAB)
+ } else { quota_mnt_getvfsmnt(mntf, list); }
+ (void)fclose(mntf);
+ }
+#endif
+#if HAVE_GETMNTENT && defined(_PATH_MNTTAB)
+ } else { quota_mnt_getmntent(mntf, list); }
+ (void)endmntent(mntf);
+ }
+#endif
+#if HAVE_GETMNTENT && defined(MNTTABNAME)
+ } else { quota_mnt_getmntent(mntf, list); }
+ (void)endmntent(mntf);
+ }
+#endif
+#if HAVE_GETMNTENT && defined(MNT_MNTTAB)
+ } else { quota_mnt_getmntent(mntf, list); }
+ (void)endmntent(mntf);
+ }
+#endif
+#if HAVE_GETMNTENT && defined(_PATH_MOUNTED)
+ } else { quota_mnt_getmntent(mntf, list); }
+ (void)endmntent(mntf);
+ }
+#endif
+ return(*list);
+}
+
+void
+quota_mnt_freelist(quota_mnt_t *list)
+{
+ quota_mnt_t *l = list, *p = NULL;
+
+ while(l != NULL) {
+ while(l->next != NULL) {
+ p = l;
+ l = l->next;
+ }
+ if(p != NULL) {
+ p->next = NULL;
+ }
+ free(l->dir);
+ free(l->device);
+ free(l);
+ p = NULL;
+ if(l != list) {
+ l = list;
+ } else {
+ l = NULL;
+ }
+ }
+}
+
--- /dev/null
+/**
+ * collectd - src/quota_mnt.h
+ * Copyright (C) 2005 Niki W. Waibel
+ *
+ * This program is free software; you can redistribute it and/
+ * or modify it under the terms of the GNU General Public Li-
+ * cence as published by the Free Software Foundation; either
+ * version 2 of the Licence, or any later version.
+ *
+ * This program is distributed in the hope that it will be use-
+ * ful, but WITHOUT ANY WARRANTY; without even the implied war-
+ * ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public Licence for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * Licence along with this program; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
+ * USA.
+ *
+ * Author:
+ * Niki W. Waibel <niki.waibel@gmx.net>
+**/
+
+#if !COLLECTD_QUOTA_MNT_H
+#define COLLECTD_QUOTA_MNT_H 1
+
+#include "common.h"
+
+#define QMO_NONE (0)
+#define QMO_USRQUOTA (1)
+#define QMO_GRPQUOTA (2)
+
+typedef struct _quota_mnt_t quota_mnt_t;
+struct _quota_mnt_t {
+ char *dir;
+ char *device;
+ int opts;
+ quota_mnt_t *next;
+};
+
+quota_mnt_t *quota_mnt_getlist(quota_mnt_t **list);
+void quota_mnt_freelist(quota_mnt_t *list);
+
+#endif /* !COLLECTD_QUOTA_MNT_H */
+
--- /dev/null
+/**
+ * collectd - src/quota_mntopt.h
+ * Copyright (C) 2005 Niki W. Waibel
+ *
+ * This program is free software; you can redistribute it and/
+ * or modify it under the terms of the GNU General Public Li-
+ * cence as published by the Free Software Foundation; either
+ * version 2 of the Licence, or any later version.
+ *
+ * This program is distributed in the hope that it will be use-
+ * ful, but WITHOUT ANY WARRANTY; without even the implied war-
+ * ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public Licence for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * Licence along with this program; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
+ * USA.
+ *
+ * Author:
+ * Niki W. Waibel <niki.waibel@gmx.net>
+**/
+
+#if !COLLECTD_QUOTA_MNTOPT_H
+#define COLLECTD_QUOTA_MNTOPT_H 1
+
+#include "common.h"
+
+/* filesystem type */
+#ifndef MNTTYPE_AUTOFS
+#define MNTTYPE_AUTOFS "autofs" /* Automount mountpoint */
+#endif
+#ifndef MNTTYPE_CAPIFS
+#define MNTTYPE_CAPIFS "capifs" /* */
+#endif
+#ifndef MNTTYPE_CRAMFS
+#define MNTTYPE_CRAMFS "cramfs" /* */
+#endif
+#ifndef MNTTYPE_DEVPTS
+#define MNTTYPE_DEVPTS "devpts" /* */
+#endif
+#ifndef MNTTYPE_EXT2
+#define MNTTYPE_EXT2 "ext2" /* 2nd Extended file system */
+#endif
+#ifndef MNTTYPE_EXT3
+#define MNTTYPE_EXT3 "ext3" /* ext2 + journaling */
+#endif
+#ifndef MNTTYPE_FUSE
+#define MNTTYPE_FUSE "fuse" /* */
+#endif
+#ifndef MNTTYPE_HSFS
+#define MNTTYPE_HSFS "hsfs" /* */
+#endif
+#ifndef MNTTYPE_ISO9660
+#define MNTTYPE_ISO9660 "iso9660" /* */
+#endif
+#ifndef MNTTYPE_JFS
+#define MNTTYPE_JFS "jfs" /* JFS file system */
+#endif
+#ifndef MNTTYPE_MINIX
+#define MNTTYPE_MINIX "minix" /* MINIX file system */
+#endif
+#ifndef MNTTYPE_NFS
+#define MNTTYPE_NFS "nfs" /* */
+#endif
+#ifndef MNTTYPE_NFS4
+#define MNTTYPE_NFS4 "nfs4" /* NFSv4 filesystem */
+#endif
+#ifndef MNTTYPE_NTFS
+#define MNTTYPE_NTFS "ntfs" /* */
+#endif
+#ifndef MNTTYPE_PROC
+#define MNTTYPE_PROC "proc" /* */
+#endif
+#ifndef MNTTYPE_RAMFS
+#define MNTTYPE_RAMFS "ramfs" /* */
+#endif
+#ifndef MNTTYPE_ROMFS
+#define MNTTYPE_ROMFS "romfs" /* */
+#endif
+#ifndef MNTTYPE_RELAYFS
+#define MNTTYPE_RELAYFS "relayfs" /* */
+#endif
+#ifndef MNTTYPE_REISER
+#define MNTTYPE_REISER "reiserfs" /* Reiser file system */
+#endif
+#ifndef MNTTYPE_SYSFS
+#define MNTTYPE_SYSFS "sysfs" /* */
+#endif
+#ifndef MNTTYPE_TMPFS
+#define MNTTYPE_TMPFS "tmpfs" /* */
+#endif
+#ifndef MNTTYPE_USBFS
+#define MNTTYPE_USBFS "usbfs" /* */
+#endif
+#ifndef MNTTYPE_UDF
+#define MNTTYPE_UDF "udf" /* OSTA UDF file system */
+#endif
+#ifndef MNTTYPE_UFS
+#define MNTTYPE_UFS "ufs" /* UNIX file system */
+#endif
+#ifndef MNTTYPE_XFS
+#define MNTTYPE_XFS "xfs" /* SGI XFS file system */
+#endif
+#ifndef MNTTYPE_VFAT
+#define MNTTYPE_VFAT "vfat" /* */
+#endif
+#ifndef MNTTYPE_ZFS
+#define MNTTYPE_ZFS "zfs" /* */
+#endif
+
+/* mount options */
+#ifndef MNTOPT_RO
+#define MNTOPT_RO "ro" /* */
+#endif
+#ifndef MNTOPT_RQ
+#define MNTOPT_RQ "rq" /* */
+#endif
+#ifndef MNTOPT_PUBLIC
+#define MNTOPT_PUBLIC "public" /* */
+#endif
+#ifndef MNTOPT_NOQUOTA
+#define MNTOPT_NOQUOTA "noquota" /* don't enforce quota */
+#endif
+#ifndef MNTOPT_QUOTA
+#define MNTOPT_QUOTA "quota" /* enforce user quota */
+#endif
+#ifndef MNTOPT_USRQUOTA
+#define MNTOPT_USRQUOTA "usrquota" /* enforce user quota */
+#endif
+#ifndef MNTOPT_USRJQUOTA
+#define MNTOPT_USRJQUOTA "usrjquota" /* enforce user quota */
+#endif
+#ifndef MNTOPT_GRPQUOTA
+#define MNTOPT_GRPQUOTA "grpquota" /* enforce group quota */
+#endif
+#ifndef MNTOPT_GRPJQUOTA
+#define MNTOPT_GRPJQUOTA "grpjquota" /* enforce group quota */
+#endif
+#ifndef MNTOPT_RSQUASH
+#define MNTOPT_RSQUASH "rsquash" /* root as ordinary user */
+#endif
+#ifndef MNTOPT_BIND
+#define MNTOPT_BIND "bind" /* binded mount */
+#endif
+#ifndef MNTOPT_LOOP
+#define MNTOPT_LOOP "loop" /* loopback mount */
+#endif
+#ifndef MNTOPT_JQFMT
+#define MNTOPT_JQFMT "jqfmt" /* journaled quota format */
+#endif
+
+#endif /* !COLLECTD_QUOTA_MNTOPT_H */
+
--- /dev/null
+/**
+ * collectd - src/quota_plugin.c
+ * Copyright (C) 2005 Niki W. Waibel
+ *
+ * This program is free software; you can redistribute it and/
+ * or modify it under the terms of the GNU General Public Li-
+ * cence as published by the Free Software Foundation; either
+ * version 2 of the Licence, or any later version.
+ *
+ * This program is distributed in the hope that it will be use-
+ * ful, but WITHOUT ANY WARRANTY; without even the implied war-
+ * ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public Licence for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * Licence along with this program; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
+ * USA.
+ *
+ * Author:
+ * Niki W. Waibel <niki.waibel@gmx.net>
+**/
+
+#include "common.h"
+#include "plugin.h"
+
+#include "quota_debug.h"
+#include "quota_mnt.h"
+#include "quota_fs.h"
+#include "quota_plugin.h"
+
+#define MODULE_NAME "quota"
+
+/* *** *** *** local constants *** *** *** */
+
+static const char *quota_filename_template = "quota-%s.rrd";
+
+static char *quota_ds_def[] =
+{
+ "DS:blocks:GAUGE:25:0:U",
+ "DS:block_quota:GAUGE:25:-1:U",
+ "DS:block_limit:GAUGE:25:-1:U",
+ "DS:block_grace:GAUGE:25:0:U",
+ "DS:block_timeleft:GAUGE:25:0:U",
+ "DS:inodes:GAUGE:25:0:U",
+ "DS:inode_quota:GAUGE:25:-1:U",
+ "DS:inode_limit:GAUGE:25:-1:U",
+ "DS:inode_grace:GAUGE:25:0:U",
+ "DS:inode_timeleft:GAUGE:25:0:U",
+ NULL
+};
+static const int quota_ds_num = 10;
+
+/* *** *** *** local functions *** *** *** */
+
+#define BUFSIZE 1024
+static void
+quota_submit(quota_t *q)
+{
+ char buf[BUFSIZE];
+ int r;
+
+ r = snprintf(buf, BUFSIZE,
+ "%u:%llu:%lld:%lld:%llu:%llu:%llu:%lld:%lld:%llu:%llu",
+ (unsigned int)curtime,
+ q->blocks, q->bquota, q->blimit, q->bgrace, q->btimeleft,
+ q->inodes, q->iquota, q->ilimit, q->igrace, q->itimeleft);
+ if(r < 1 || r >= BUFSIZE) {
+ DBG("failed");
+ return;
+ }
+ plugin_submit(MODULE_NAME, q->name, buf);
+}
+#undef BUFSIZE
+
+/* *** *** *** local plugin functions *** *** *** */
+
+static void
+quota_init(void)
+{
+ DBG_INIT("quota debug file opened.");
+}
+
+static void
+quota_read(void)
+{
+ quota_mnt_t *list = NULL, *l = NULL;
+ quota_t q = {
+ name: "test",
+ blocks: 0, bquota: -1, blimit: -1,
+ bgrace: 0, btimeleft: 0,
+ inodes: 0, iquota: -1, ilimit: -1,
+ igrace: 0, itimeleft: 0,
+ };
+
+ l = quota_mnt_getlist(&list);
+ DBG("local mountpoints:");
+ while(l != NULL) {
+ DBG("\tdir: %s", l->dir);
+ DBG("\tdevice: %s", l->device);
+ DBG("\topts: %s (0x%04x)",
+ (l->opts == QMO_NONE) ? "-"
+ : (l->opts == QMO_USRQUOTA) ? "USRQUOTA"
+ : (l->opts == QMO_GRPQUOTA) ? "GRPQUOTA"
+ : (l->opts == (QMO_USRQUOTA|QMO_GRPQUOTA)) ?
+ "USRQUOTA GRPQUOTA" : " ??? ",
+ l->opts);
+ l = l->next;
+ if(l != NULL) {
+ DBG("\t-- ");
+ }
+ }
+ DBG("\t== ");
+ quota_submit(&q);
+ quota_mnt_freelist(list);
+}
+
+static void
+quota_write(char *host, char *inst, char *val)
+{
+ char file[512];
+ int r;
+
+ r = snprintf(file, 512, quota_filename_template, inst);
+ if(r < 1 || r >= 512) {
+ DBG("failed");
+ return;
+ }
+
+ rrd_update_file(host, file, val, quota_ds_def, quota_ds_num);
+}
+
+/* *** *** *** global functions *** *** *** */
+
+void
+module_register(void)
+{
+ plugin_register(MODULE_NAME, quota_init, quota_read, quota_write);
+}
+
--- /dev/null
+/**
+ * collectd - src/quota_plugin.h
+ * Copyright (C) 2005 Niki W. Waibel
+ *
+ * This program is free software; you can redistribute it and/
+ * or modify it under the terms of the GNU General Public Li-
+ * cence as published by the Free Software Foundation; either
+ * version 2 of the Licence, or any later version.
+ *
+ * This program is distributed in the hope that it will be use-
+ * ful, but WITHOUT ANY WARRANTY; without even the implied war-
+ * ranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public Licence for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * Licence along with this program; if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
+ * USA.
+ *
+ * Author:
+ * Niki W. Waibel <niki.waibel@gmx.net>
+**/
+
+#if !COLLECTD_QUOTA_PLUGIN_H
+#define COLLECTD_QUOTA_PLUGIN_H 1
+
+#include "common.h"
+
+typedef struct {
+ char *name;
+ unsigned long long blocks;
+ long long bquota, blimit;
+ unsigned long long bgrace, btimeleft;
+ unsigned long long inodes;
+ long long iquota, ilimit;
+ unsigned long long igrace, itimeleft;
+} quota_t;
+
+void module_register(void);
+
+#endif /* !COLLECTD_QUOTA_PLUGIN_H */
+