Huge changes. Segfaults at the moment, but this is the way we want to go...
authorniki <niki>
Sun, 11 Dec 2005 11:30:40 +0000 (11:30 +0000)
committerniki <niki>
Sun, 11 Dec 2005 11:30:40 +0000 (11:30 +0000)
22 files changed:
build.sh
configure.in
src/Makefile.am
src/collectd.c
src/collectd.h
src/common.c [new file with mode: 0644]
src/common.h [new file with mode: 0644]
src/config.h.in
src/quota_common.c [deleted file]
src/quota_common.h [deleted file]
src/quota_debug.c [deleted file]
src/quota_debug.h [deleted file]
src/quota_fs.c
src/quota_fs.h
src/quota_mnt.c
src/quota_mnt.h
src/quota_mntopt.h [deleted file]
src/quota_plugin.c
src/utils_debug.c [new file with mode: 0644]
src/utils_debug.h [new file with mode: 0644]
src/utils_mount.c [new file with mode: 0644]
src/utils_mount.h [new file with mode: 0644]

index 852b8eb..ca41cad 100755 (executable)
--- a/build.sh
+++ b/build.sh
@@ -3,6 +3,7 @@
 set -x
 
 true \
+&& autoheader --force \
 && aclocal --force \
 && libtoolize --ltdl --force --copy \
 && automake --add-missing --copy \
index 220f51c..7556ac3 100644 (file)
@@ -24,8 +24,8 @@ AC_PROG_LIBTOOL
 AC_CONFIG_SUBDIRS(libltdl)
 
 dnl Checks for header files.
-AC_HEADER_STDC
 AC_HEADER_SYS_WAIT
+AC_CHECK_HEADERS(stdarg.h)
 AC_CHECK_HEADERS(fcntl.h)
 AC_CHECK_HEADERS(signal.h)
 AC_CHECK_HEADERS(limits.h)
@@ -71,40 +71,6 @@ AC_CHECK_FUNCS(getgrgid getpwuid)
 AC_CHECK_FUNCS(getfsent getvfsent listmntent)
 AC_FUNC_GETMNTENT
 
-def_mnt_includes="\
-/* if sthg is changed here also change it in src/quota_mnt.c!!! */
-#if HAVE_MNTENT_H
-# include <mntent.h>
-#endif
-#if HAVE_MNTTAB_H
-# include <mnttab.h>
-#endif
-#if HAVE_PATHS_H
-# include <paths.h>
-#endif
-#if HAVE_SYS_FS_TYPES_H
-# include <sys/fs_types.h>
-#endif
-#if HAVE_SYS_MNTENT_H
-# include <sys/mntent.h>
-#endif
-#if HAVE_SYS_MNTTAB_H
-# include <sys/mnttab.h>
-#endif
-#if HAVE_SYS_MOUNT_H
-# include <sys/mount.h>
-#endif
-#if HAVE_SYS_VFSTAB_H
-# include <sys/vfstab.h>
-#endif
-#if HAVE_SYS_QUOTA_H
-# include <sys/quota.h>
-#endif
-#if HAVE_SYS_VFS_H
-# include <sys/vfs.h>
-#endif
-/* END if sthg is changed here also change it in src/quota_mnt.c!!! */"
-
 if test "x$ac_cv_func_getmntent" = 'xyes'; then
        saveCFLAGS="$CFLAGS"
        CFLAGS="-Wall -Werror $CFLAGS"
@@ -112,7 +78,7 @@ if test "x$ac_cv_func_getmntent" = 'xyes'; then
                [fu_cv_getmntent1],
                AC_COMPILE_IFELSE(
                        AC_LANG_PROGRAM([[AC_INCLUDES_DEFAULT
-                                       $def_mnt_includes]],
+#include "$srcdir/src/utils_mount.h"]],
                                [[(void)getmntent((FILE *)NULL);]]
                        ),
                        [fu_cv_getmntent1=yes],
@@ -124,7 +90,7 @@ if test "x$ac_cv_func_getmntent" = 'xyes'; then
                        [fu_cv_getmntent2],
                        AC_COMPILE_IFELSE(
                                AC_LANG_PROGRAM([[AC_INCLUDES_DEFAULT
-                                               $def_mnt_includes]],
+#include "$srcdir/src/utils_mount.h"]],
                                        [[(void)getmntent((FILE *)NULL,
                                                (struct mnttab *)NULL);]]
                                ),
@@ -191,6 +157,32 @@ then
 fi
 AM_CONDITIONAL(BUILD_WITH_RRDTOOL, test "x$with_rrdtool" = "xyes")
 
+AC_ARG_WITH(pth, AC_HELP_STRING([--with-pth=PFX], [Path to pth (experimental).]),
+[      if test "x$withval" != "xno" -a "x$withval" != "xyes"
+       then
+               LDFLAGS="$LDFLAGS -L$withval/lib"
+               CPPFLAGS="$CPPFLAGS -I$withval/include"
+               with_pth="yes"
+       fi
+], [with_pth="no"])
+if test "x$with_pth" = "xyes"
+then
+       AC_CHECK_LIB(pth, pth_init,, [with_pth="no"], [])
+fi
+if test "x$with_pth" = "xyes"
+then
+       AC_CHECK_HEADERS(pth.h,, [with_pth="no"])
+fi
+if test "x$with_pth" = "xyes"
+then
+       collect_pth=1
+else
+       collect_pth=0
+fi
+AC_DEFINE_UNQUOTED(COLLECT_PTH, [$collect_pth],
+       [Wether or not to use pth (portable threads) library])
+AM_CONDITIONAL(BUILD_WITH_PTH, test "x$with_pth" = "xyes")
+
 if test "$ac_system" = "Solaris"
 then
        with_kstat="yes"
@@ -272,6 +264,46 @@ fi
 #
 # Check for enabled/disabled features
 #
+AC_ARG_ENABLE(debug, AC_HELP_STRING([--enable-debug],
+       [Enable debugging (disabled by default)]),
+       [], [enable_debug="no"])
+if test "x$enable_debug" = "xno"
+then
+       collect_debug=0
+else
+       if test "x$enable_debug" = "xyes"
+       then
+               collect_debug=1
+       else
+               AC_MSG_NOTICE([Please specify either --enable-debug or --disable-debug; Enabling debugging.])
+               collect_debug=1
+               enable_debug="yes"
+       fi
+fi
+AC_DEFINE_UNQUOTED(COLLECT_DEBUG, [$collect_debug],
+       [Wether or not to enable debugging])
+AM_CONDITIONAL(BUILD_DEBUG, test "x$enable_debug" = "xyes")
+
+AC_ARG_ENABLE(daemon, AC_HELP_STRING([--disable-daemon],
+       [Disable daemon mode (enabled by default)]),
+       [], [enable_daemon="yes"])
+if test "x$enable_daemon" = "xno"
+then
+       collect_daemon=0
+else
+       if test "x$enable_daemon" = "xyes"
+       then
+               collect_daemon=1
+       else
+               AC_MSG_NOTICE([Please specify either --enable-daemon or --disable-daemon; Enabling daemon mode.])
+               collect_daemon=1
+               enable_daemon="yes"
+       fi
+fi
+AC_DEFINE_UNQUOTED(COLLECT_DAEMON, [$collect_daemon],
+       [Wether or not to enable daemon mode])
+AM_CONDITIONAL(BUILD_DAEMON, test "x$enable_daemon" = "xyes")
+
 AC_ARG_ENABLE(cpu, AC_HELP_STRING([--disable-cpu], [Disable CPU usage statistics]),, [enable_cpu="yes"])
 if test "x$enable_cpu" != "xno"
 then
@@ -321,7 +353,7 @@ 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 statistics (experimental, disabled by default)]),
        [], [enable_quota="no"])
 if test "x$enable_quota" = "xno"
 then
@@ -330,7 +362,6 @@ 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
@@ -338,7 +369,7 @@ else
        fi
 fi
 AC_DEFINE_UNQUOTED(COLLECT_QUOTA, [$collect_quota],
-       [Wether or not to collect quotastats])
+       [Wether or not to collect quota statistics])
 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"])
@@ -510,15 +541,20 @@ cat <<EOF;
 Configuration:
   Libraries:
     librrd  . . . . . . $with_rrdtool
+    libpth  . . . . . . $with_pth (experimental)
     lm_sensors  . . . . $with_lm_sensors
     libstatgrab . . . . $with_libstatgrab
     libkstat  . . . . . $with_kstat
 
   Features:
+    debug . . . . . . . $enable_debug
+    daemon mode . . . . $enable_daemon
+
+  Modules:
     cpu . . . . . . . . $enable_cpu
     cpufreq . . . . . . $enable_cpufreq
     disk  . . . . . . . $enable_disk
-    quota . . . . . . . $enable_quota
+    quota . . . . . . . $enable_quota (experimental)
     hddtemp . . . . . . $enable_hddtemp
     load  . . . . . . . $enable_load
     memory  . . . . . . $enable_memory
index 0b693f9..dc189d4 100644 (file)
@@ -5,12 +5,15 @@ endif
 sbin_PROGRAMS = collectd
 
 collectd_SOURCES = collectd.c collectd.h \
+                  utils_debug.c utils_debug.h \
+                  utils_mount.c utils_mount.h \
                   common.c common.h \
                   multicast.c multicast.h \
                   plugin.c plugin.h
 #collectd_CFLAGS = -DPLUGINDIR='"$(pkglibdir)"'
 collectd_CPPFLAGS = -DLOCALSTATEDIR='"$(localstatedir)"' -DPLUGINDIR='"$(pkglibdir)"'
 collectd_LDFLAGS = -export-dynamic
+collectd_CFLAGS = -Werror
 collectd_LDADD = $(LIBLTDL) "-dlopen" self
 collectd_DEPENDENCIES = $(LIBLTDL)
 if BUILD_WITH_RRDTOOL
@@ -46,10 +49,8 @@ endif
 if BUILD_MODULE_QUOTA
 pkglib_LTLIBRARIES += quota.la
 quota_la_SOURCES = quota_plugin.c quota_plugin.h
-quota_la_SOURCES += quota_common.c quota_common.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_SOURCES += quota_mnt.c quota_mnt.h
 quota_la_LDFLAGS = -module -avoid-version
 quota_la_CFLAGS = -Werror
 collectd_LDADD += "-dlopen" quota.la
index dabc346..31f473e 100644 (file)
@@ -211,7 +211,9 @@ int pidfile_remove (void)
 int main (int argc, char **argv)
 {
        struct sigaction sigIntAction, sigChldAction;
+#if COLLECTD_DAEMON
        pid_t pid;
+#endif
 
        char *plugindir = NULL;
        char *basedir = DATADIR;
@@ -314,7 +316,7 @@ int main (int argc, char **argv)
        /*
         * fork off child
         */
-#if DEBUG == 0
+#if COLLECTD_DAEMON
        if (daemonize)
        {
                if ((pid = fork ()) == -1)
@@ -358,7 +360,7 @@ int main (int argc, char **argv)
                        return (1);
                }
        } /* if (daemonize) */
-#endif
+#endif /* COLLECTD_DAEMON */
 
        /*
         * run the actual loops
index 72b2246..a66647a 100644 (file)
@@ -5,6 +5,9 @@
 # include "config.h"
 #endif
 
+#if HAVE_STDARG_H
+# include <stdarg.h>
+#endif
 #include <stdio.h>
 #if HAVE_SYS_TYPES_H
 # include <sys/types.h>
 #include <statgrab.h>
 #endif
 
-#ifndef DEBUG
-#define DEBUG 0
-#endif
-
 #ifndef LOCALSTATEDIR
 #define LOCALSTATEDIR "/opt/collectd/var"
 #endif
diff --git a/src/common.c b/src/common.c
new file mode 100644 (file)
index 0000000..d946cfb
--- /dev/null
@@ -0,0 +1,306 @@
+/**
+ * collectd - src/common.c
+ * Copyright (C) 2005  Florian octo Forster
+ *
+ * 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.
+ *
+ * Authors:
+ *   Florian octo Forster <octo at verplant.org>
+ *   Niki W. Waibel <niki.waibel@gmx.net>
+**/
+
+#include "common.h"
+#include "utils_debug.h"
+
+#ifdef HAVE_LIBKSTAT
+extern kstat_ctl_t *kc;
+#endif
+
+#ifdef HAVE_LIBRRD
+static char *rra_def[] =
+{
+               "RRA:AVERAGE:0.2:6:1500",
+               "RRA:AVERAGE:0.1:180:1680",
+               "RRA:AVERAGE:0.1:2160:1520",
+               "RRA:MIN:0.2:6:1500",
+               "RRA:MIN:0.1:180:1680",
+               "RRA:MIN:0.1:2160:1520",
+               "RRA:MAX:0.2:6:1500",
+               "RRA:MAX:0.1:180:1680",
+               "RRA:MAX:0.1:2160:1520",
+               NULL
+};
+static int rra_num = 9;
+#endif /* HAVE_LIBRRD */
+
+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 *r = malloc(size);
+       if(r == NULL) {
+               DBG("Not enough memory.");
+               exit(3);
+       }
+       return r;
+}
+
+int strsplit (char *string, char **fields, size_t size)
+{
+       size_t i;
+       char *ptr;
+
+       i = 0;
+       ptr = string;
+       while ((fields[i] = strtok (ptr, " \t")) != NULL)
+       {
+               ptr = NULL;
+               i++;
+
+               if (i >= size)
+                       break;
+       }
+
+       return (i);
+}
+
+#ifdef HAVE_LIBRRD
+int check_create_dir (char *dir)
+{
+       struct stat statbuf;
+
+       if (stat (dir, &statbuf) == -1)
+       {
+               if (errno == ENOENT)
+               {
+                       if (mkdir (dir, 0755) == -1)
+                       {
+                               syslog (LOG_ERR, "mkdir %s: %s", dir, strerror (errno));
+                               return (-1);
+                       }
+               }
+               else
+               {
+                       syslog (LOG_ERR, "stat %s: %s", dir, strerror (errno));
+                       return (-1);
+               }
+       }
+       else if (!S_ISDIR (statbuf.st_mode))
+       {
+               syslog (LOG_ERR, "stat %s: Not a directory!", dir);
+               return (-1);
+       }
+
+       return (0);
+}
+
+int rrd_create_file (char *filename, char **ds_def, int ds_num)
+{
+       char **argv;
+       int argc;
+       int i, j;
+       int status = 0;
+
+       argc = ds_num + rra_num + 4;
+
+       if ((argv = (char **) malloc (sizeof (char *) * (argc + 1))) == NULL)
+       {
+               syslog (LOG_ERR, "rrd_create failed: %s", strerror (errno));
+               return (-1);
+       }
+
+       argv[0] = "create";
+       argv[1] = filename;
+       argv[2] = "-s";
+       argv[3] = "10";
+
+       j = 4;
+       for (i = 0; i < ds_num; i++)
+               argv[j++] = ds_def[i];
+       for (i = 0; i < rra_num; i++)
+               argv[j++] = rra_def[i];
+       argv[j] = NULL;
+
+       optind = 0; /* bug in librrd? */
+       rrd_clear_error ();
+       if (rrd_create (argc, argv) == -1)
+       {
+               syslog (LOG_ERR, "rrd_create failed: %s: %s", filename, rrd_get_error ());
+               status = -1;
+       }
+
+       free (argv);
+       
+       return (status);
+}
+#endif /* HAVE_LIBRRD */
+
+int rrd_update_file (char *host, char *file, char *values,
+               char **ds_def, int ds_num)
+{
+#ifdef HAVE_LIBRRD
+       struct stat statbuf;
+       char full_file[1024];
+       char *argv[4] = { "update", full_file, values, NULL };
+
+       /* host == NULL => local mode */
+       if (host != NULL)
+       {
+               if (check_create_dir (host))
+                       return (-1);
+
+               if (snprintf (full_file, 1024, "%s/%s", host, file) >= 1024)
+                       return (-1);
+       }
+       else
+       {
+               if (snprintf (full_file, 1024, "%s", file) >= 1024)
+                       return (-1);
+       }
+
+       if (stat (full_file, &statbuf) == -1)
+       {
+               if (errno == ENOENT)
+               {
+                       if (rrd_create_file (full_file, ds_def, ds_num))
+                               return (-1);
+               }
+               else
+               {
+                       syslog (LOG_ERR, "stat %s: %s", full_file, strerror (errno));
+                       return (-1);
+               }
+       }
+       else if (!S_ISREG (statbuf.st_mode))
+       {
+               syslog (LOG_ERR, "stat %s: Not a regular file!", full_file);
+               return (-1);
+       }
+
+       optind = 0; /* bug in librrd? */
+       rrd_clear_error ();
+       if (rrd_update (3, argv) == -1)
+       {
+               syslog (LOG_WARNING, "rrd_update failed: %s: %s", full_file, rrd_get_error ());
+               return (-1);
+       }
+#endif /* HAVE_LIBRRD */
+
+       return (0);
+}
+
+#ifdef HAVE_LIBKSTAT
+int get_kstat (kstat_t **ksp_ptr, char *module, int instance, char *name)
+{
+       char ident[128];
+       
+       if (kc == NULL)
+               return (-1);
+
+       snprintf (ident, 128, "%s,%i,%s", module, instance, name);
+       ident[127] = '\0';
+
+       if (*ksp_ptr == NULL)
+       {
+               if ((*ksp_ptr = kstat_lookup (kc, module, instance, name)) == NULL)
+               {
+                       syslog (LOG_ERR, "Cound not find kstat %s", ident);
+                       return (-1);
+               }
+
+               if ((*ksp_ptr)->ks_type != KSTAT_TYPE_NAMED)
+               {
+                       syslog (LOG_WARNING, "kstat %s has wrong type", ident);
+                       *ksp_ptr = NULL;
+                       return (-1);
+               }
+       }
+
+#ifdef assert
+       assert (*ksp_ptr != NULL);
+       assert ((*ksp_ptr)->ks_type == KSTAT_TYPE_NAMED);
+#endif
+
+       if (kstat_read (kc, *ksp_ptr, NULL) == -1)
+       {
+               syslog (LOG_WARNING, "kstat %s could not be read", ident);
+               return (-1);
+       }
+
+       if ((*ksp_ptr)->ks_type != KSTAT_TYPE_NAMED)
+       {
+               syslog (LOG_WARNING, "kstat %s has wrong type", ident);
+               return (-1);
+       }
+
+       return (0);
+}
+
+long long get_kstat_value (kstat_t *ksp, char *name)
+{
+       kstat_named_t *kn;
+       long long retval = -1LL;
+
+#ifdef assert
+       assert (ksp != NULL);
+       assert (ksp->ks_type == KSTAT_TYPE_NAMED);
+#else
+       if (ksp == NULL)
+       {
+               fprintf (stderr, "ERROR: %s:%i: ksp == NULL\n", __FILE__, __LINE__);
+               return (-1LL);
+       }
+       else if (ksp->ks_type != KSTAT_TYPE_NAMED)
+       {
+               fprintf (stderr, "ERROR: %s:%i: ksp->ks_type != KSTAT_TYPE_NAMED\n", __FILE__, __LINE__);
+               return (-1LL);
+       }
+#endif
+
+       if ((kn = (kstat_named_t *) kstat_data_lookup (ksp, name)) == NULL)
+               return (retval);
+
+       if (kn->data_type == KSTAT_DATA_INT32)
+               retval = (long long) kn->value.i32;
+       else if (kn->data_type == KSTAT_DATA_UINT32)
+               retval = (long long) kn->value.ui32;
+       else if (kn->data_type == KSTAT_DATA_INT64)
+               retval = (long long) kn->value.i64; /* According to ANSI C99 `long long' must hold at least 64 bits */
+       else if (kn->data_type == KSTAT_DATA_UINT64)
+               retval = (long long) kn->value.ui64; /* XXX: Might overflow! */
+       else
+               syslog (LOG_WARNING, "get_kstat_value: Not a numeric value: %s", name);
+                
+       return (retval);
+}
+#endif /* HAVE_LIBKSTAT */
diff --git a/src/common.h b/src/common.h
new file mode 100644 (file)
index 0000000..89cae6a
--- /dev/null
@@ -0,0 +1,26 @@
+#ifndef COMMON_H
+#define COMMON_H
+
+#include "collectd.h"
+
+#define sfree(ptr) \
+       if((ptr) != NULL) { \
+               free(ptr); \
+       } \
+       (ptr) = NULL
+
+void sstrncpy(char *d, const char *s, int len);
+char *sstrdup(const char *s);
+void *smalloc(size_t size);
+
+int strsplit (char *string, char **fields, size_t size);
+
+int rrd_update_file (char *host, char *file, char *values, char **ds_def,
+               int ds_num);
+
+#ifdef HAVE_LIBKSTAT
+int get_kstat (kstat_t **ksp_ptr, char *module, int instance, char *name);
+long long get_kstat_value (kstat_t *ksp, char *name);
+#endif
+
+#endif /* COMMON_H */
index 6a91b3f..746d711 100644 (file)
@@ -6,6 +6,12 @@
 /* Wether or not to collect cpu frequency statistics */
 #undef COLLECT_CPUFREQ
 
+/* Wether or not to enable daemon mode */
+#undef COLLECT_DAEMON
+
+/* Wether or not to enable debugging */
+#undef COLLECT_DEBUG
+
 /* Wether or not to collect diskstats */
 #undef COLLECT_DISK
 
 /* Wether or not to collect processes statistics */
 #undef COLLECT_PROCESSES
 
-/* Wether or not to collect quotastats */
+/* Wether or not to use pth (portable threads) library */
+#undef COLLECT_PTH
+
+/* Wether or not to collect quota statistics */
 #undef COLLECT_QUOTA
 
 /* Wether or not to collect lm_sensors statistics */
 /* Define to 1 if you have the `nsl' library (-lnsl). */
 #undef HAVE_LIBNSL
 
+/* Define to 1 if you have the `pth' library (-lpth). */
+#undef HAVE_LIBPTH
+
 /* Define to 1 if you have the `resolv' library (-lresolv). */
 #undef HAVE_LIBRESOLV
 
 /* Define to 1 if you have the <paths.h> header file. */
 #undef HAVE_PATHS_H
 
+/* Define to 1 if you have the <pth.h> header file. */
+#undef HAVE_PTH_H
+
 /* Define to 1 if you have the <pwd.h> header file. */
 #undef HAVE_PWD_H
 
 /* Define to 1 if you have the <statgrab.h> header file. */
 #undef HAVE_STATGRAB_H
 
+/* Define to 1 if you have the <stdarg.h> header file. */
+#undef HAVE_STDARG_H
+
 /* Define to 1 if you have the <stdint.h> header file. */
 #undef HAVE_STDINT_H
 
diff --git a/src/quota_common.c b/src/quota_common.c
deleted file mode 100644 (file)
index 7d50742..0000000
+++ /dev/null
@@ -1,64 +0,0 @@
-/**
- * collectd - src/quota_common.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_common.h"
-
-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 *r = malloc(size);
-       if(r == NULL) {
-               DBG("Not enough memory.");
-               exit(3);
-       }
-       return r;
-}
-
-void
-sfree(void *ptr)
-{
-       if(ptr != NULL) {
-               free(ptr);
-       }
-}
-
diff --git a/src/quota_common.h b/src/quota_common.h
deleted file mode 100644 (file)
index c05b2dc..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-/**
- * collectd - src/quota_common.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>
-**/
-
-#include "common.h"
-
-void sstrncpy(char *d, const char *s, int len);
-char *sstrdup(const char *s);
-void *smalloc(size_t size);
-void sfree(void *ptr);
-
diff --git a/src/quota_debug.c b/src/quota_debug.c
deleted file mode 100644 (file)
index acaa94c..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-/**
- * 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
-
diff --git a/src/quota_debug.h b/src/quota_debug.h
deleted file mode 100644 (file)
index 6d0d747..0000000
+++ /dev/null
@@ -1,61 +0,0 @@
-/**
- * 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
-#define QUOTA_PLUGIN_DEBUG_FILE "collectd_quota.log"
-
-#if QUOTA_PLUGIN_DEBUG
-       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(QUOTA_PLUGIN_DEBUG_FILE, "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 */
-
index bbacafa..57044e8 100644 (file)
@@ -22,8 +22,7 @@
 **/
 
 #include "common.h"
-#include "quota_debug.h"
-#include "quota_common.h"
+#include "utils_debug.h"
 #include "quota_mnt.h"
 #include "quota_fs.h"
 
@@ -64,11 +63,11 @@ getquota_ext3(quota_t **quota, quota_mnt_t *m)
        uint32_t fmt;
 #endif
 #if HAVE_QUOTACTL
-       if(quotactl(QCMD(Q_GETFMT, USRQUOTA), m->device,
+       if(quotactl(QCMD(Q_GETFMT, USRQUOTA), m->m->device,
                0, (void *)&fmt) == -1)
        {
                DBG("quotactl (Q_GETFMT, USRQUOTA) returned -1 on"
-                       " %s: %s", m->device, strerror(errno));
+                       " %s: %s", m->m->device, strerror(errno));
                return NULL;
        }
        if(fmt == 1) {
@@ -108,39 +107,39 @@ DBG("start");
 
 #if HAVE_QUOTACTL
        if(m->opts & QMO_USRQUOTA) {
-               if(quotactl(QCMD(Q_GETINFO, USRQUOTA), m->device,
+               if(quotactl(QCMD(Q_GETINFO, USRQUOTA), m->m->device,
                        0, (void *)&dqiusr) == -1)
                {
                        DBG("quotactl (Q_GETINFO, USRQUOTA) returned -1 on"
-                               " %s: %s", m->device, strerror(errno));
+                               " %s: %s", m->m->device, strerror(errno));
                        m->opts &= ~QMO_USRQUOTA;
                        DBG("\tusrquota switched off");
                }
        }
        if(m->opts & QMO_USRQUOTA) {
-               if(quotactl(QCMD(Q_SYNC, USRQUOTA), m->device, 0, NULL) == -1)
+               if(quotactl(QCMD(Q_SYNC, USRQUOTA), m->m->device, 0, NULL) == -1)
                {
                        DBG("quotactl (Q_SYNC, USRQUOTA) returned -1 on"
-                               " %s: %s", m->device, strerror(errno));
+                               " %s: %s", m->m->device, strerror(errno));
                        m->opts &= ~QMO_USRQUOTA;
                        DBG("\tusrquota switched off");
                }
        }
        if(m->opts & QMO_GRPQUOTA) {
-               if(quotactl(QCMD(Q_GETINFO, GRPQUOTA), m->device,
+               if(quotactl(QCMD(Q_GETINFO, GRPQUOTA), m->m->device,
                        0, (void *)&dqigrp) == -1)
                {
                        DBG("quotactl (Q_GETINFO, GRPQUOTA) returned -1 on"
-                               " %s: %s", m->device, strerror(errno));
+                               " %s: %s", m->m->device, strerror(errno));
                        m->opts &= ~QMO_GRPQUOTA;
                        DBG("\tgrpquota switched off");
                }
        }
        if(m->opts & QMO_GRPQUOTA) {
-               if(quotactl(QCMD(Q_SYNC, GRPQUOTA), m->device, 0, NULL) == -1)
+               if(quotactl(QCMD(Q_SYNC, GRPQUOTA), m->m->device, 0, NULL) == -1)
                {
                        DBG("quotactl (Q_SYNC, GRPQUOTA) returned -1 on"
-                               " %s: %s", m->device, strerror(errno));
+                               " %s: %s", m->m->device, strerror(errno));
                        m->opts &= ~QMO_GRPQUOTA;
                        DBG("\tgrpquota switched off");
                }
@@ -159,11 +158,11 @@ DBG("start");
                char *qfname = NULL;
                if(m->usrjquota == NULL) {
                        char *qfn;
-                       qfname = (char *)smalloc(strlen(m->dir)
+                       qfname = (char *)smalloc(strlen(m->m->dir)
                                + 1 + strlen("aquota.user") + 1);
                        qfn = qfname;
-                       sstrncpy(qfn, m->dir, strlen(m->dir) + 1);
-                       qfn += strlen(m->dir);
+                       sstrncpy(qfn, m->m->dir, strlen(m->m->dir) + 1);
+                       qfn += strlen(m->m->dir);
                        if(qfn[-1] != '/') {
                                sstrncpy(qfn, "/", 2);
                                qfn += 1;
@@ -171,11 +170,11 @@ DBG("start");
                        sstrncpy(qfn, "aquota.user", strlen("aquota.user") + 1);
                } else {
                        char *qfn;
-                       qfname = (char *)smalloc(strlen(m->dir)
+                       qfname = (char *)smalloc(strlen(m->m->dir)
                                + 1 + strlen(m->usrjquota) + 1);
                        qfn = qfname;
-                       sstrncpy(qfn, m->dir, strlen(m->dir) + 1);
-                       qfn += strlen(m->dir);
+                       sstrncpy(qfn, m->m->dir, strlen(m->m->dir) + 1);
+                       qfn += strlen(m->m->dir);
                        if(qfn[-1] != '/') {
                                sstrncpy(qfn, "/", 2);
                                qfn += 1;
@@ -194,18 +193,18 @@ DBG("start");
                for(i=0; i<0x1000; i++) {
                        struct dqblk dqb;
                        if(quotactl(QCMD(Q_GETQUOTA, USRQUOTA),
-                               m->device, i, (void *)&dqb) == -1)
+                               m->m->device, i, (void *)&dqb) == -1)
                        {
 #if 0
                                DBG("quotactl (Q_GETQUOTA, USRQUOTA)"
                                        " returned -1 on %d %s: %s",
-                                       i, m->device, strerror(errno));
+                                       i, m->m->device, strerror(errno));
 #endif
                                continue;
                        }
                        DBG("quotactl (Q_GETQUOTA, USRQUOTA)"
                                " returned ok on %d %s",
-                               i, m->device);
+                               i, m->m->device);
                        if(*quota == NULL) {
                                *quota = (quota_t *)smalloc(sizeof(quota_t));
                                q = *quota;
@@ -222,7 +221,7 @@ DBG("start");
                        q->name = sstrdup(buf);
 #endif
                        q->id = sstrdup(buf);
-                       q->dir = sstrdup(m->dir);
+                       q->dir = sstrdup(m->m->dir);
                        q->blocks = dqb.dqb_curspace;
                        q->bquota = dqb.dqb_bsoftlimit << 10;
                        q->blimit = dqb.dqb_bhardlimit << 10;
@@ -241,18 +240,18 @@ DBG("start");
                for(i=0; i<0x1000; i++) {
                        struct dqblk dqb;
                        if(quotactl(QCMD(Q_GETQUOTA, GRPQUOTA),
-                               m->device, i, (void *)&dqb) == -1)
+                               m->m->device, i, (void *)&dqb) == -1)
                        {
 #if 0
                                DBG("quotactl (Q_GETQUOTA, GRPQUOTA)"
                                        " returned -1 on %d %s: %s",
-                                       i, m->device, strerror(errno));
+                                       i, m->m->device, strerror(errno));
 #endif
                                continue;
                        }
                        DBG("quotactl (Q_GETQUOTA, GRPQUOTA)"
                                " returned ok on %d %s",
-                               i, m->device);
+                               i, m->m->device);
                        if(*quota == NULL) {
                                *quota = (quota_t *)smalloc(sizeof(quota_t));
                                q = *quota;
@@ -269,7 +268,7 @@ DBG("start");
                        q->name = sstrdup(buf);
 #endif
                        q->id = sstrdup(buf);
-                       q->dir = sstrdup(m->dir);
+                       q->dir = sstrdup(m->m->dir);
                        q->blocks = dqb.dqb_curspace;
                        q->bquota = dqb.dqb_bsoftlimit << 10;
                        q->blimit = dqb.dqb_bhardlimit << 10;
@@ -424,7 +423,7 @@ quota_fs_getquota(quota_t **quota, quota_mnt_t *mnt)
        quota_t *q = NULL, *qlast = NULL;
 
        while(m != NULL) {
-               switch(quota_mnt_type(m->type)) {
+               switch(quota_mnt_type(m->m->type)) {
                  case QMT_EXT2:
                  case QMT_EXT3: 
                        qlast = getquota_ext3(&q, m);
index b689ae8..3404dfe 100644 (file)
@@ -25,7 +25,7 @@
 #define COLLECTD_QUOTA_FS_H 1
 
 #include "common.h"
-#include "quota_debug.h"
+#include "utils_debug.h"
 #include "quota_mnt.h"
 
 /* Quota Filesystem Type */
index 50b0f4f..1917a59 100644 (file)
@@ -22,8 +22,7 @@
 **/
 
 #include "common.h"
-#include "quota_debug.h"
-#include "quota_common.h"
+#include "utils_debug.h"
 #include "quota_fs.h"
 #include "quota_mnt.h"
 
 #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];
-};
-
-/* 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;
-#if HAVE_XFS_XQM_H
-       struct xfs_super_block xfsb;
-#endif
-       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((int)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((int)c)) {
-               return (c - '0');
-       } else if(islower((int)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((int)s[0]) || !isxdigit((int)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);
-}
-
-static char *
-get_device_name(const char *item)
-{
-       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;
-}
-
-/*
- *      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 */
-       }
-       sfree((char *)dev);
-       return ret;
-}
-#endif /* HAVE_XFS_XQM_H */
-
-
-#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 */
-
-char *
-quota_mnt_checkmountopt(char *line, char *keyword, int full)
-{
-       char *line2, *l2;
-       int l = strlen(keyword);
-       char *p1, *p2;
-
-       if(line == NULL || keyword == NULL) {
-               return NULL;
-       }
-       if(full != 0) {
-               full = 1;
-       }
-
-       line2 = sstrdup(line);
-       l2 = line2;
-       while(*l2 != '\0') {
-               if(*l2 == ',') {
-                       *l2 = '\0';
-               }
-               l2++;
-       }
-
-       p1 = line - 1;
-       p2 = strchr(line, ',');
-       do {
-               if(strncmp(line2+(p1-line)+1, keyword, l+full) == 0) {
-                       free(line2);
-                       return p1+1;
-               }
-               p1 = p2;
-               if(p1 != NULL) {
-                       p2 = strchr(p1+1, ',');
-               }
-       } while(p1 != NULL);
-
-       free(line2);
-       return NULL;
-} /* char *quota_mnt_checkmountopt(char *line, char *keyword, int full) */
-
-char *
-quota_mnt_getmountopt(char *line, char *keyword)
-{
-       char *r;
-
-       r = quota_mnt_checkmountopt(line, keyword, 0);
-       if(r != NULL) {
-               char *p;
-               r += strlen(keyword);
-               p = strchr(r, ',');
-               if(p == NULL) {
-                       if(strlen(r) == 0) {
-                               return NULL;
-                       }
-                       return sstrdup(r);
-               } else {
-                       char *m;
-                       if((p-r) == 1) {
-                               return NULL;
-                       }
-                       m = (char *)smalloc(p-r+1);
-                       sstrncpy(m, r, p-r+1);
-                       return m;
-               }
-       }
-       return r;
-} /* char *quota_mnt_getmountopt(char *line, char *keyword) */
-
+#if 0
 #if HAVE_GETMNTENT
 static quota_mnt_t *
 quota_mnt_getmntent(FILE *mntf, quota_mnt_t **list)
@@ -538,7 +107,7 @@ quota_mnt_getmntent(FILE *mntf, quota_mnt_t **list)
                        continue;
                }
 
-               if(quota_mnt_checkmountopt(mnt->mnt_opts, MNTOPT_NOQUOTA, 1) != NULL) {
+               if(quota_mnt_checkmountopt(mnt->mnt_opts, "noquota", 1) != NULL) {
                        DBG("noquota option on fs (%s) %s (%s): ignored",
                                mnt->mnt_type, mnt->mnt_dir, mnt->mnt_fsname);
                        continue;
@@ -563,17 +132,17 @@ quota_mnt_getmntent(FILE *mntf, quota_mnt_t **list)
                        device = loop;
                }
 
-               if(quota_mnt_checkmountopt(mnt->mnt_opts, MNTOPT_QUOTA, 1) != NULL) {
+               if(quota_mnt_checkmountopt(mnt->mnt_opts, "quota", 1) != NULL) {
                        opts |= QMO_USRQUOTA;
                }
-               if(quota_mnt_checkmountopt(mnt->mnt_opts, MNTOPT_USRQUOTA, 1) != NULL) {
+               if(quota_mnt_checkmountopt(mnt->mnt_opts, "usrquota", 1) != NULL) {
                        opts |= QMO_USRQUOTA;
                }
                usrjquota = quota_mnt_getmountopt(mnt->mnt_opts, "usrjquota=");
                if(usrjquota != NULL) {
                        opts |= QMO_USRQUOTA;
                }
-               if(quota_mnt_checkmountopt(mnt->mnt_opts, MNTOPT_GRPQUOTA, 1) != NULL) {
+               if(quota_mnt_checkmountopt(mnt->mnt_opts, "grpquota", 1) != NULL) {
                        opts |= QMO_GRPQUOTA;
                }
                grpjquota = quota_mnt_getmountopt(mnt->mnt_opts, "grpjquota=");
@@ -583,7 +152,7 @@ quota_mnt_getmntent(FILE *mntf, quota_mnt_t **list)
                jqfmt = quota_mnt_getmountopt(mnt->mnt_opts, "jqfmt=");
 
 #if HAVE_XFS_XQM_H
-               if(!strcmp(mnt->mnt_type, MNTTYPE_XFS)) {
+               if(!strcmp(mnt->mnt_type, "xfs")) {
                        if(hasxfsquota(mnt, USRQUOTA) == 0
                        && hasxfsquota(mnt, GRPQUOTA) == 0)
                        {
@@ -622,10 +191,10 @@ quota_mnt_getmntent(FILE *mntf, quota_mnt_t **list)
                        last->next = (quota_mnt_t *)smalloc(sizeof(quota_mnt_t));
                        last = last->next;
                }
-               last->dir = sstrdup(mnt->mnt_dir);
-               last->device = device;
-               last->type = sstrdup(mnt->mnt_type);
-               last->options = sstrdup(mnt->mnt_opts);
+               last->m->dir = sstrdup(mnt->mnt_dir);
+               last->m->device = device;
+               last->m->type = sstrdup(mnt->mnt_type);
+               last->m->options = sstrdup(mnt->mnt_opts);
                last->usrjquota = usrjquota;
                last->grpjquota = grpjquota;
                last->jqfmt = jqfmt;
@@ -636,89 +205,23 @@ quota_mnt_getmntent(FILE *mntf, quota_mnt_t **list)
        return last;
 } /* static quota_mnt_t *quota_mnt_getmntent(FILE *mntf, quota_mnt_t **list) */
 #endif /* HAVE_GETMNTENT */
-
+#endif
 
 
 quota_mnt_t *
 quota_mnt_getlist(quota_mnt_t **list)
 {
+       cu_mount_t *fulllist = NULL, *fl;
        quota_mnt_t *last = NULL;
 
-       /* 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;
+       (void)cu_mount_getlist(&fulllist);
+       fl = fulllist;
+       while(fl != NULL) {
 
-       if(listmntent(&mntlist, KMTAB, NULL, NULL) < 0) {
-               DBG("calling listmntent() failed: %s", strerror(errno));
-#endif
-               /* give up */
-               DBG("failed get local mountpoints");
-               return(NULL);
+               fl = fl->next;
+       } /* while(fl != NULL) */
+       cu_mount_freelist(fulllist);
 
-#if HAVE_LISTMNTENT
-       } else { last = quota_mnt_listmntent(mntlist, list); }
-       freemntlist(mntlist);
-       }
-#endif
-#if HAVE_GETVFSENT && defined(VFSTAB)
-       } else { last = quota_mnt_getvfsmnt(mntf, list); }
-       (void)fclose(mntf);
-       }
-#endif
-#if HAVE_GETMNTENT && defined(_PATH_MNTTAB)
-       } else { last = quota_mnt_getmntent(mntf, list); }
-       (void)endmntent(mntf);
-       }
-#endif
-#if HAVE_GETMNTENT && defined(MNTTABNAME)
-       } else { last = quota_mnt_getmntent(mntf, list); }
-       (void)endmntent(mntf);
-       }
-#endif
-#if HAVE_GETMNTENT && defined(MNT_MNTTAB)
-       } else { last = quota_mnt_getmntent(mntf, list); }
-       (void)endmntent(mntf);
-       }
-#endif
-#if HAVE_GETMNTENT && defined(_PATH_MOUNTED)
-       } else { last = quota_mnt_getmntent(mntf, list); }
-       (void)endmntent(mntf);
-       }
-#endif
        return(last);
 } /* quota_mnt_t *quota_mnt_getlist(quota_mnt_t **list) */
 
@@ -735,10 +238,10 @@ quota_mnt_freelist(quota_mnt_t *list)
                if(p != NULL) {
                        p->next = NULL;
                }
-               sfree(l->dir);
-               sfree(l->device);
-               sfree(l->type);
-               sfree(l->options);
+               sfree(l->m->dir);
+               sfree(l->m->device);
+               sfree(l->m->type);
+               sfree(l->m->options);
                sfree(l->usrjquota);
                sfree(l->grpjquota);
                sfree(l->jqfmt);
@@ -752,16 +255,4 @@ quota_mnt_freelist(quota_mnt_t *list)
        } /* while(l != NULL) */
 } /* void quota_mnt_freelist(quota_mnt_t *list) */
 
-int
-quota_mnt_type(const char *type)
-{
-       if(strcmp(type, "ext3") == 0) return QMT_EXT3;
-       if(strcmp(type, "ext2") == 0) return QMT_EXT2;
-       if(strcmp(type, "ufs")  == 0) return QMT_UFS;
-       if(strcmp(type, "vxfs") == 0) return QMT_VXFS;
-       if(strcmp(type, "zfs")  == 0) return QMT_ZFS;
-       return QMT_UNKNOWN;
-} /* int quota_mnt_type(const char *type) */
-
-
 
index 36484f8..e5893b9 100644 (file)
@@ -25,6 +25,7 @@
 #define COLLECTD_QUOTA_MNT_H 1
 
 #include "common.h"
+#include "utils_mount.h"
 
 /* Quota Mount Type */
 #define QMT_UNKNOWN (0)
 
 typedef struct _quota_mnt_t quota_mnt_t;
 struct _quota_mnt_t {
-       char *dir;         /* "/sys" or "/" */
-       char *device;      /* "none" or "/dev/hda1" */
-       char *type;        /* "sysfs" or "ext3" */
-       char *options;     /* "rw,noatime,commit=600,quota,grpquota" */
+       cu_mount_t *m;
        char *usrjquota;   /* "q.u" */
        char *grpjquota;   /* "q.g" */
        char *jqfmt;       /* "TODO" */
diff --git a/src/quota_mntopt.h b/src/quota_mntopt.h
deleted file mode 100644 (file)
index 1160f35..0000000
+++ /dev/null
@@ -1,154 +0,0 @@
-/**
- * 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 */
-
index d2d629a..6dac92c 100644 (file)
@@ -23,9 +23,8 @@
 
 #include "common.h"
 #include "plugin.h"
+#include "utils_debug.h"
 
-#include "quota_debug.h"
-#include "quota_common.h"
 #include "quota_mnt.h"
 #include "quota_fs.h"
 #include "quota_plugin.h"
@@ -106,7 +105,7 @@ quota_submit(quota_t *q)
 static void
 quota_init(void)
 {
-       DBG_INIT("quota debug file opened.");
+       DBG_STARTFILE("quota debug file opened.");
 }
 
 static void
@@ -119,10 +118,11 @@ quota_read(void)
        l = list;
        DBG("local mountpoints:");
        while(l != NULL) {
-               DBG("\tdir: %s", l->dir);
-               DBG("\tdevice: %s", l->device);
-               DBG("\ttype: %s", l->type);
-               DBG("\toptions: %s", l->options);
+               DBG("\tdir: %s", l->m->dir);
+               DBG("\tspec_device: %s", l->m->spec_device);
+               DBG("\tdevice: %s", l->m->device);
+               DBG("\ttype: %s", l->m->type);
+               DBG("\toptions: %s", l->m->options);
                DBG("\tusrjquota: %s", l->usrjquota);
                DBG("\tgrpjquota: %s", l->grpjquota);
                DBG("\tjqfmt: %s", l->jqfmt);
diff --git a/src/utils_debug.c b/src/utils_debug.c
new file mode 100644 (file)
index 0000000..c839ade
--- /dev/null
@@ -0,0 +1,196 @@
+/**
+ * collectd - src/utils_debug.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 "utils_debug.h"
+
+/* *** *** ***   global variables   *** *** *** */
+#if COLLECT_DEBUG
+
+#define DEFAULT_FILENAME "collectd.log"
+
+static void cu_vdebug(const char *file, int line, const char *func,
+       const char *format, va_list ap);
+
+/* if preemptive threads are used, these vars need some sort of locking! */
+/* pth is non-preemptive, so no locking is necessary (?) */
+static FILE *cu_debug_file = NULL;
+static char *cu_debug_filename = NULL;
+
+static void
+cu_vdebug(const char *file, int line, const char *func,
+       const char *format, va_list ap)
+{ 
+       FILE *f;
+       if(cu_debug_file != NULL) {
+               f = cu_debug_file;
+       } else {
+               /* stderr might be redirected to /dev/null. in that case */
+               /* you'll not see anything... */
+               f = stderr;
+       }
+
+       fprintf(f, "%s:%d:%s(): ",
+               file, line, func);
+       vfprintf(f, format, ap);
+       fprintf(f, "\n");
+       fflush(f);
+} /* static void cu_vdebug(const char *file, int line, const char *func,
+       const char *format, va_list ap) */
+
+void
+cu_debug(const char *file, int line, const char *func,
+       const char *format, ...)
+{ 
+       va_list ap;
+
+       va_start(ap, format);
+       cu_vdebug(file, line, func, format, ap);
+       va_end(ap);
+} /* void cu_debug(const char *file, int line, const char *func,
+       const char *format, ...) */
+
+int
+cu_debug_startfile(const char *file, int line, const char *func,
+       const char *format, ...)
+{
+       va_list ap;
+
+       if(cu_debug_file != NULL) {
+               DBG("Don't call this function more then once without"
+                       " calling cu_debug_stopfile().");
+               return EXIT_FAILURE;
+       }
+
+       if(cu_debug_filename == NULL) {
+               cu_debug_filename = sstrdup(DEFAULT_FILENAME);
+       }
+
+       cu_debug_file = fopen(cu_debug_filename, "a");
+       if(cu_debug_file == NULL) {
+               DBG("Cannot open debug file %s: %s.\n",
+                       cu_debug_filename, strerror(errno));
+               return EXIT_FAILURE;
+       }
+
+       va_start(ap, format);
+       cu_vdebug(file, line, func, format, ap);
+       va_end(ap);
+
+       return EXIT_SUCCESS;
+} /* int cu_debug_start(const char *file, int line, const char *func,
+       const char *format, ...) */
+
+int
+cu_debug_stopfile(const char *file, int line, const char *func,
+       const char *format, ...)
+{
+       va_list ap;
+
+       va_start(ap, format);
+       cu_vdebug(file, line, func, format, ap);
+       va_end(ap);
+
+       if(cu_debug_file == NULL) {
+               DBG("Don't call this function more then once or without"
+                       " calling cu_debug_startfile().");
+               return EXIT_FAILURE;
+       }
+
+       if(fclose(cu_debug_file) != 0) {
+               DBG("Cannot close debug file %s: %s.\n",
+                       cu_debug_filename, strerror(errno));
+               return EXIT_FAILURE;
+       }
+       cu_debug_file = NULL;
+
+       sfree(cu_debug_filename);
+
+       return EXIT_SUCCESS;
+} /* int cu_debug_stop(const char *file, int line, const char *func,
+       const char *format, ...) */
+
+int
+cu_debug_resetfile(const char *file, int line, const char *func,
+       const char *filename)
+{
+       if(filename == NULL) {
+               DBG("You have to set filename when calling this function!\n");
+               return EXIT_FAILURE;
+       }
+       if(cu_debug_file != NULL) {
+               char *save_filename = NULL;
+
+               /* DBG_STARTFILE was called already */
+               /* reopen file */
+
+               DBG_STOPFILE("Closing %s and reopening %s.",
+                       cu_debug_filename, filename);
+               save_filename = smalloc(strlen(cu_debug_filename)+1);
+               sstrncpy(save_filename, cu_debug_filename,
+                       strlen(cu_debug_filename)+1);
+               cu_debug_filename = smalloc(strlen(filename)+1);
+               sstrncpy(cu_debug_filename, filename, strlen(filename)+1);
+               DBG_STARTFILE("Reopening %s after closing %s.",
+                       filename, save_filename);
+               sfree(save_filename);
+               return EXIT_SUCCESS;
+       }
+
+       /* DBG_STARTFILE was NOT called already */
+       /* setting filename only */
+
+       if(cu_debug_filename != NULL) {
+               sfree(cu_debug_filename);
+       }
+       cu_debug_filename = smalloc(strlen(filename)+1);
+       sstrncpy(cu_debug_filename, filename, strlen(filename)+1);
+
+       return EXIT_SUCCESS;
+} /* int cu_debug_resetfile(const char *file, int line, const char *func,
+        const char *filename) */
+
+#else /* !COLLECT_DEBUG */
+
+void
+cu_debug(const char *file, int line, const char *func, const char *format, ...)
+{
+}
+int
+cu_debug_startfile(const char *file, int line, const char *func, char *format, ...)
+{
+       return EXIT_SUCCESS;
+}
+int
+cu_debug_stopfile(const char *file, int line, const char *func, char *format, ...)
+{
+       return EXIT_SUCCESS;
+}
+int
+cu_debug_setfile(const char *file, int line, const char *func, char *filename)
+{
+       return EXIT_SUCCESS;
+}
+
+#endif /* COLLECT_DEBUG */
+
diff --git a/src/utils_debug.h b/src/utils_debug.h
new file mode 100644 (file)
index 0000000..a7b1971
--- /dev/null
@@ -0,0 +1,50 @@
+/**
+ * collectd - src/utils_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_UTILS_DEBUG_H
+#define COLLECTD_UTILS_DEBUG_H 1
+
+#define DBG(...) cu_debug(__FILE__, __LINE__, __func__, \
+       __VA_ARGS__)
+
+#define DBG_STARTFILE(...) cu_debug_startfile(__FILE__, __LINE__, \
+       __func__, __VA_ARGS__)
+#define DBG_STOPFILE(...) cu_debug_stopfile(__FILE__, __LINE__, \
+       __func__, __VA_ARGS__)
+
+#define DBG_SETFILE(file) cu_debug_setfile(__FILE__, __LINE__, __func__, \
+       filename)
+
+void cu_debug(const char *file, int line, const char *func,
+       const char *format, ...);
+
+int cu_debug_startfile(const char *file, int line, const char *func,
+       const char *format, ...);
+int cu_debug_stopfile(const char *file, int line, const char *func,
+       const char *format, ...);
+
+int cu_debug_setfile(const char *file, int line, const char *func,
+       char *filename);
+
+#endif /* !COLLECTD_UTILS_DEBUG_H */
+
diff --git a/src/utils_mount.c b/src/utils_mount.c
new file mode 100644 (file)
index 0000000..74bc02f
--- /dev/null
@@ -0,0 +1,602 @@
+/**
+ * collectd - src/utils_mount.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"
+#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 "utils_debug.h"
+#include "utils_mount.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];
+};
+
+/* 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;
+#if HAVE_XFS_XQM_H
+       struct xfs_super_block xfsb;
+#endif
+       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((int)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((int)c)) {
+               return (c - '0');
+       } else if(islower((int)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((int)s[0]) || !isxdigit((int)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);
+}
+
+static char *
+get_device_name(const char *item)
+{
+       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;
+}
+
+#if HAVE_LISTMNTENT
+static void
+cu_mount_listmntent(struct tabmntent *mntlist, cu_mount_t **list)
+{
+       struct *p;
+       struct mntent *mnt;
+
+       for(p = mntlist; p; p = p->next) {
+               mnt = p->ment;
+               *list = smalloc(sizeof(cu_mount_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
+cu_mount_getvfsmnt(FILE *mntf, cu_mount_t **list)
+{
+       DBG("TODO: getvfsmnt");
+       *list = NULL;
+}
+#endif /* HAVE_GETVFSENT */
+
+char *
+cu_mount_checkmountopt(char *line, char *keyword, int full)
+{
+       char *line2, *l2;
+       int l = strlen(keyword);
+       char *p1, *p2;
+
+       if(line == NULL || keyword == NULL) {
+               return NULL;
+       }
+       if(full != 0) {
+               full = 1;
+       }
+
+       line2 = sstrdup(line);
+       l2 = line2;
+       while(*l2 != '\0') {
+               if(*l2 == ',') {
+                       *l2 = '\0';
+               }
+               l2++;
+       }
+
+       p1 = line - 1;
+       p2 = strchr(line, ',');
+       do {
+               if(strncmp(line2+(p1-line)+1, keyword, l+full) == 0) {
+                       free(line2);
+                       return p1+1;
+               }
+               p1 = p2;
+               if(p1 != NULL) {
+                       p2 = strchr(p1+1, ',');
+               }
+       } while(p1 != NULL);
+
+       free(line2);
+       return NULL;
+} /* char *cu_mount_checkmountopt(char *line, char *keyword, int full) */
+
+char *
+cu_mount_getmountopt(char *line, char *keyword)
+{
+       char *r;
+
+       r = cu_mount_checkmountopt(line, keyword, 0);
+       if(r != NULL) {
+               char *p;
+               r += strlen(keyword);
+               p = strchr(r, ',');
+               if(p == NULL) {
+                       if(strlen(r) == 0) {
+                               return NULL;
+                       }
+                       return sstrdup(r);
+               } else {
+                       char *m;
+                       if((p-r) == 1) {
+                               return NULL;
+                       }
+                       m = (char *)smalloc(p-r+1);
+                       sstrncpy(m, r, p-r+1);
+                       return m;
+               }
+       }
+       return r;
+} /* char *cu_mount_getmountopt(char *line, char *keyword) */
+
+#if HAVE_GETMNTENT
+static cu_mount_t *
+cu_mount_getmntent(FILE *mntf, cu_mount_t **list)
+{
+       cu_mount_t *last = *list;
+       struct mntent *mnt;
+
+#if HAVE_GETMNTENT1
+       while((mnt = getmntent(mntf)) != NULL) {
+#endif /* HAVE_GETMNTENT1 */
+               char *loop = NULL, *device = NULL;
+
+#if 1
+               DBG("------------------ BEGIN");
+               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
+
+               loop = cu_mount_getmountopt(mnt->mnt_opts, "loop=");
+               if(loop == NULL) {   /* no loop= mount */
+                       device = get_device_name(mnt->mnt_fsname);
+                       if(device == NULL) {
+                               DBG("can't get devicename for fs (%s) %s (%s)"
+                                       ": ignored", mnt->mnt_type,
+                                       mnt->mnt_dir, mnt->mnt_fsname);
+                               continue;
+                       }
+               } else {
+                       device = loop;
+               }
+
+#if 1
+               DBG("device          %s", device);
+               DBG("------------------ END");
+#endif
+               if(*list == NULL) {
+                       *list = (cu_mount_t *)smalloc(sizeof(cu_mount_t));
+                       last = *list;
+               } else {
+                       last->next = (cu_mount_t *)smalloc(sizeof(cu_mount_t));
+                       last = last->next;
+               }
+               last->dir = sstrdup(mnt->mnt_dir);
+               last->spec_device = sstrdup(mnt->mnt_fsname);
+               last->device = device;
+               last->type = sstrdup(mnt->mnt_type);
+               last->options = sstrdup(mnt->mnt_opts);
+               last->next = NULL;
+       } /* while((mnt = getmntent(mntf)) != NULL) */
+
+       return last;
+} /* static cu_mount_t *cu_mount_getmntent(FILE *mntf, cu_mount_t **list) */
+#endif /* HAVE_GETMNTENT */
+
+
+
+cu_mount_t *
+cu_mount_getlist(cu_mount_t **list)
+{
+       cu_mount_t *last = NULL;
+
+       /* 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");
+               return(NULL);
+
+#if HAVE_LISTMNTENT
+       } else { last = cu_mount_listmntent(mntlist, list); }
+       freemntlist(mntlist);
+       }
+#endif
+#if HAVE_GETVFSENT && defined(VFSTAB)
+       } else { last = cu_mount_getvfsmnt(mntf, list); }
+       (void)fclose(mntf);
+       }
+#endif
+#if HAVE_GETMNTENT && defined(_PATH_MNTTAB)
+       } else { last = cu_mount_getmntent(mntf, list); }
+       (void)endmntent(mntf);
+       }
+#endif
+#if HAVE_GETMNTENT && defined(MNTTABNAME)
+       } else { last = cu_mount_getmntent(mntf, list); }
+       (void)endmntent(mntf);
+       }
+#endif
+#if HAVE_GETMNTENT && defined(MNT_MNTTAB)
+       } else { last = cu_mount_getmntent(mntf, list); }
+       (void)endmntent(mntf);
+       }
+#endif
+#if HAVE_GETMNTENT && defined(_PATH_MOUNTED)
+       } else { last = cu_mount_getmntent(mntf, list); }
+       (void)endmntent(mntf);
+       }
+#endif
+       return(last);
+} /* cu_mount_t *cu_mount_getlist(cu_mount_t **list) */
+
+void
+cu_mount_freelist(cu_mount_t *list)
+{
+       cu_mount_t *l = list, *p = NULL;
+
+       while(l != NULL) {
+               while(l->next != NULL) {
+                       p = l;
+                       l = l->next;
+               }
+               if(p != NULL) {
+                       p->next = NULL;
+               }
+               sfree(l->dir);
+               sfree(l->spec_device);
+               sfree(l->device);
+               sfree(l->type);
+               sfree(l->options);
+               sfree(l);
+               p = NULL;
+               if(l != list) {
+                       l = list;
+               } else {
+                       l = NULL;
+               }
+       } /* while(l != NULL) */
+} /* void cu_mount_freelist(cu_mount_t *list) */
+
+int
+cu_mount_type(const char *type)
+{
+       if(strcmp(type, "ext3") == 0) return CUMT_EXT3;
+       if(strcmp(type, "ext2") == 0) return CUMT_EXT2;
+       if(strcmp(type, "ufs")  == 0) return CUMT_UFS;
+       if(strcmp(type, "vxfs") == 0) return CUMT_VXFS;
+       if(strcmp(type, "zfs")  == 0) return CUMT_ZFS;
+       return CUMT_UNKNOWN;
+} /* int cu_mount_type(const char *type) */
+
+
+
diff --git a/src/utils_mount.h b/src/utils_mount.h
new file mode 100644 (file)
index 0000000..3f357b8
--- /dev/null
@@ -0,0 +1,108 @@
+/**
+ * collectd - src/utils_mount.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_UTILS_MOUNT_H
+#define COLLECTD_UTILS_MOUNT_H 1
+
+#if HAVE_MNTENT_H
+# include <mntent.h>
+#endif
+#if HAVE_MNTTAB_H
+# include <mnttab.h>
+#endif
+#if HAVE_PATHS_H
+# include <paths.h>
+#endif
+#if HAVE_SYS_FS_TYPES_H
+# include <sys/fs_types.h>
+#endif
+#if HAVE_SYS_MNTENT_H
+# include <sys/mntent.h>
+#endif
+#if HAVE_SYS_MNTTAB_H
+# include <sys/mnttab.h>
+#endif
+#if HAVE_SYS_MOUNT_H
+# include <sys/mount.h>
+#endif
+#if HAVE_SYS_VFSTAB_H
+# include <sys/vfstab.h>
+#endif
+#if HAVE_SYS_VFS_H
+# include <sys/vfs.h>
+#endif
+
+#include "common.h"
+
+/* Collectd Utils Mount Type */
+#define CUMT_UNKNOWN (0)
+#define CUMT_EXT2    (1)
+#define CUMT_EXT3    (2)
+#define CUMT_XFS     (3)
+#define CUMT_UFS     (4)
+#define CUMT_VXFS    (5)
+#define CUMT_ZFS     (6)
+
+/* Collectd Utils Mount Options */
+#define CUMO_NONE     (0)
+#define CUMO_USRQUOTA (1)
+#define CUMO_GRPQUOTA (2)
+
+typedef struct _cu_mount_t cu_mount_t;
+struct _cu_mount_t {
+       char *dir;         /* "/sys" or "/" */
+       char *spec_device; /* "LABEL=/" or "none" or "proc" or "/dev/hda1" */
+       char *device;      /* "none" or "proc" "/dev/hda1" */
+       char *type;        /* "sysfs" or "ext3" */
+       char *options;     /* "rw,noatime,commit=600,quota,grpquota" */
+       cu_mount_t *next;
+};
+
+int cu_mount_type(const char *type);
+
+char *cu_mount_getmountopt(char *line, char *keyword);
+char *cu_mount_checkmountopt(char *line, char *keyword, int full);
+
+/*
+  DESCRIPTION
+       The cu_mount_getlist() function creates a list
+       of all mountpoints.
+
+       If *list is NULL, a new list is created and *list is
+       set to point to the first entry.
+
+       If *list is set, the list is appended and *list is
+       not changed.
+
+  RETURN VALUE
+       The cu_mount_getlist() function returns a pointer to
+       the last entry of the list, or NULL if an error occured.
+
+  NOTES
+       In case of an error, *list is not modified.
+*/
+cu_mount_t *cu_mount_getlist(cu_mount_t **list);
+void cu_mount_freelist(cu_mount_t *list);
+
+#endif /* !COLLECTD_UTILS_MOUNT_H */
+