Merged revisions 495:504, 508:509 and 510:513 from `trunk' to `tags/collectd-3.8.1'
authorocto <octo>
Mon, 13 Mar 2006 20:19:52 +0000 (20:19 +0000)
committerocto <octo>
Mon, 13 Mar 2006 20:19:52 +0000 (20:19 +0000)
12 files changed:
ChangeLog
collectd.spec
configure.in
debian/changelog
debian/collectd.init.d
debian/collectd.postinst
debian/control
src/collectd.pod
src/common.c
src/liboping/liboping.c
src/liboping/liboping.h
src/utils_mount.c

index 0622b1d..76273a4 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,7 @@
+2006-03-13, Version 3.8.1
+       * Fixes for building collectd unter FreeBSD, Mac OS X and Solaris.
+       * Fixes in the debian `postinst' and `init.d' scripts.
+
 2006-03-09, Version 3.8.0
        * The `ping' plugin no longer uses `libping' but a self written
          library named `liboping'. With this library it's possible to ping
index da1259f..41d2cbe 100644 (file)
@@ -1,6 +1,6 @@
 Summary:       Statistics collection daemon for filling RRD files.
 Name:           collectd
-Version:       3.7.2
+Version:       3.8.1
 Release:       1
 Source:                http://verplant.org/collectd/%{name}-%{version}.tar.gz
 License:       GPL
@@ -88,6 +88,9 @@ rm -rf $RPM_BUILD_ROOT
 %attr(0444,root,root) %{_libdir}/%{name}/sensors.so*
 
 %changelog
+* Thu Mar 13 2006 Florian octo Forster <octo@verplant.org> 3.8.1-1
+- New upstream version
+
 * Thu Mar 09 2006 Florian octo Forster <octo@verplant.org> 3.8.0-1
 - New upstream version
 
index ebb2cd0..1c8617d 100644 (file)
@@ -1,5 +1,5 @@
 dnl Process this file with autoconf to produce a configure script.
-AC_INIT(collectd, 3.8.0)
+AC_INIT(collectd, 3.8.1)
 AC_CONFIG_SRCDIR(src/collectd.c)
 AC_CONFIG_HEADERS(src/config.h)
 AM_INIT_AUTOMAKE(dist-bzip2)
@@ -30,8 +30,10 @@ AC_CONFIG_SUBDIRS(libltdl src/libconfig)
 #
 # Checks for header files.
 #
+AC_HEADER_STDC
 AC_HEADER_SYS_WAIT
 AC_HEADER_DIRENT
+AC_CHECK_HEADERS(stdint.h)
 AC_CHECK_HEADERS(errno.h)
 AC_CHECK_HEADERS(syslog.h)
 AC_CHECK_HEADERS(fcntl.h)
@@ -42,10 +44,94 @@ AC_CHECK_HEADERS(sys/socket.h)
 AC_CHECK_HEADERS(sys/select.h)
 AC_CHECK_HEADERS(netdb.h)
 AC_CHECK_HEADERS(arpa/inet.h)
-AC_CHECK_HEADERS(netinet/in.h)
 AC_CHECK_HEADERS(sys/resource.h)
 AC_CHECK_HEADERS(sys/param.h)
 
+# For ping library
+AC_CHECK_HEADERS(netinet/in_systm.h, [], [],
+[#if HAVE_STDINT_H
+# include <stdint.h>
+#endif
+])
+AC_CHECK_HEADERS(netinet/in.h, [], [],
+[#if HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#if HAVE_NETINET_IN_SYSTM_H
+# include <netinet/in_systm.h>
+#endif
+])
+AC_CHECK_HEADERS(netinet/ip.h, [], [],
+[#if HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#if HAVE_NETINET_IN_SYSTM_H
+# include <netinet/in_systm.h>
+#endif
+#if HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+])
+AC_CHECK_HEADERS(netinet/ip_icmp.h, [], [],
+[#if HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#if HAVE_NETINET_IN_SYSTM_H
+# include <netinet/in_systm.h>
+#endif
+#if HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+#if HAVE_NETINET_IP_H
+# include <netinet/ip.h>
+#endif
+])
+AC_CHECK_HEADERS(netinet/ip_var.h, [], [],
+[#if HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#if HAVE_NETINET_IN_SYSTM_H
+# include <netinet/in_systm.h>
+#endif
+#if HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+#if HAVE_NETINET_IP_H
+# include <netinet/ip.h>
+#endif
+])
+AC_CHECK_HEADERS(netinet/ip6.h, [], [],
+[#if HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_NETINET_IN_SYSTM_H
+# include <netinet/in_systm.h>
+#endif
+#if HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+])
+AC_CHECK_HEADERS(netinet/icmp6.h, [], [],
+[#if HAVE_STDINT_H
+# include <stdint.h>
+#endif
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_NETINET_IN_SYSTM_H
+# include <netinet/in_systm.h>
+#endif
+#if HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+#if HAVE_NETINET_IP6_H
+# include <netinet/ip6.h>
+#endif
+])
+
 # For cpu modules
 AC_CHECK_HEADERS(sys/sysctl.h sys/dkstat.h)
 
@@ -123,7 +209,26 @@ AC_CHECK_FUNCS(getgrgid getpwuid)
 
 # For mount interface
 AC_CHECK_FUNCS(getfsent getvfsent listmntent)
+AC_CHECK_FUNCS(getfsstat)
+
+# Check for different versions of `getmntent' here..
 AC_FUNC_GETMNTENT
+if test "x$ac_cv_lib_sun_getmntent" = "xyes"
+then
+       AC_DEFINE(HAVE_SUN_GETMNTENT, 1,
+                 [Define if the function getmntent exists. It's the version from libsun.])
+fi
+if test "x$ac_cv_lib_seq_getmntent" = "xyes"
+then
+       AC_DEFINE(HAVE_SEQ_GETMNTENT, 1,
+                 [Define if the function getmntent exists. It's the version from libseq.])
+fi
+if test "x$ac_cv_lib_gen_getmntent" = "xyes"
+then
+       AC_DEFINE(HAVE_GEN_GETMNTENT, 1,
+                 [Define if the function getmntent exists. It's the version from libgen.])
+fi
+
 if test "x$ac_cv_func_getmntent" = "xyes"; then
        saveCFLAGS="$CFLAGS"
        CFLAGS="-Wall -Werror $CFLAGS"
index 409ada8..0a7872d 100644 (file)
@@ -1,3 +1,15 @@
+collectd (3.8.1-1) unstable; urgency=low
+
+  * New upstream version
+
+ -- Florian Forster <octo@verplant.org>  Mon, 13 Mar 2006 21:09:09 +0200
+
+collectd (3.8.0-2) unstable; urgency=low
+
+  * Much improved init script. Thanks to Sebastian for his work :)
+
+ -- Florian Forster <octo@verplant.org>  Sat, 11 Mar 2006 16:09:44 +0200
+
 collectd (3.8.0-1) unstable; urgency=low
 
   * New upstream version
index c9d950f..0503ec9 100755 (executable)
@@ -1,9 +1,8 @@
-#!/bin/sh
+#!/bin/bash
 #
 # collectd     Initscript for collectd
 #              http://verplant.org/collectd/
-# Author:      Florian Forster <octo@verplant.org>
-# Extended to support multiple running instances of collectd:
+# Authors:     Florian Forster <octo@verplant.org>
 #              Sebastian Harl <sh@tokkee.org>
 #
 
@@ -32,31 +31,41 @@ fi
 #      Function that starts the daemon/service.
 #
 d_start() {
-       i=1
+       i=0
        
-       if [[ ! -d "$CONFIGDIR" && -e "$FALLBACKCONF" ]]
+       if [ ! -d "$CONFIGDIR" -a -e "$FALLBACKCONF" ]
        then
                start-stop-daemon --start --quiet --exec $DAEMON \
                        -- -C "$FALLBACKCONF"
        else
-               echo -n " ("
-               for CONFIG in `cd $CONFIGDIR; ls *.conf 2> /dev/null`; do
-                       CONF="$CONFIGDIR/$CONFIG"
-                       NAME=${CONFIG%%.conf}
-                       PIDFILE=$( grep PIDFile $CONF | awk '{print $2}' )
+               for FILE in `ls $CONFIGDIR/*.conf 2>/dev/null`
+               do
+                       NAME=`basename "$FILE" .conf`
 
-                       if [ 1 != $i ]; then
-                               echo -n " "
+                       if [ $i == 0 ]
+                       then
+                               echo -n " (";
+                       else
+                               echo -n ", ";
+                       fi
+                       
+                       $DAEMON -C "$FILE" 2>/dev/null
+                       if [ $? == 0 ]
+                       then
+                               echo -n "$NAME";
+                       else
+                               echo -n "$NAME failed";
                        fi
 
-                       start-stop-daemon --start --quiet \
-                               --pidfile $PIDFILE --startas $DAEMON \
-                               -- -C "$CONFIGDIR/$CONFIG"
-                       echo -n "$NAME"
-
-                       let i++
+                       i=$(($i+1))
                done
-               echo -n ")"
+
+               if [ $i == 0 ]
+               then
+                       echo -n "[no config found]";
+               else
+                       echo -n ")"
+               fi
        fi
 }
 
index d1aa19c..05ce45d 100755 (executable)
@@ -19,7 +19,7 @@ case "$1" in
        configure)
                [ -d /etc/collectd ] || mkdir -p /etc/collectd
                
-               if [ -e /etc/collectd.conf && ! -e /etc/collectd/default.conf ]; then
+               if [ -e /etc/collectd.conf -a ! -e /etc/collectd/default.conf ]; then
                        mv /etc/collectd.conf /etc/collectd/default.conf
                fi
        ;;
index 2df65f6..9b3b9ca 100644 (file)
@@ -8,7 +8,7 @@ Standards-Version: 3.6.1
 Package: collectd
 Architecture: any
 Depends: libc6, librrd0 | librrd2
-Suggests: collectd-mysql, collectd-sensors
+Suggests: collectd-mysql, collectd-sensors, librrds-perl
 Description: Statistics collection daemon for filling RRD files.
  collectd is a small daemon written in C for performance. It reads various
  system statistics and updates RRD files, creating them if neccessary. Since
index db0e8ba..4591994 100644 (file)
@@ -118,9 +118,9 @@ collectd is linked against C<librrd>.
 The other two modes, B<client mode> and B<server mode>, are used to send data
 over a network and receive it again.
 
-In B<client mode> the daemon collectd the data locally and send it's result to
-one or more network addresses. No RRD files are written in this case. This is
-the only mode available if collectd is not linked against C<librrd>.
+In B<client mode> the daemon collects the data locally and sends it's results
+to one or more network addresses. No RRD files are written in this case. This
+is the only mode available if collectd is not linked against C<librrd>.
 
 If started in B<server mode> the daemon will listen on one or more interfaces
 and write the data it receives to RRD files. No data is collected locally.
index 43a51a5..50a563a 100644 (file)
@@ -56,6 +56,9 @@ char *sstrdup (const char *s)
 {
        char *r;
 
+       if (s == NULL)
+               return (NULL);
+
        if((r = strdup (s)) == NULL)
        {
                DBG ("Not enough memory.");
index 6f7d079..b57f8e2 100644 (file)
  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
  */
 
-#include <stdlib.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <errno.h>
-#include <string.h>
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
 
-#include <assert.h>
+#if STDC_HEADERS
+# include <stdlib.h>
+# include <stdio.h>
+# include <string.h>
+# include <errno.h>
+# include <assert.h>
+#else
+# error "You don't have the standard C99 header files installed"
+#endif /* STDC_HEADERS */
 
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
 
-#include <sys/socket.h>
-#include <netdb.h>
+#if HAVE_FCNTL_H
+# include <fcntl.h>
+#endif
+#if HAVE_SYS_TYPES_H
+# include <sys/types.h>
+#endif
+#if HAVE_SYS_STAT_H
+# include <sys/stat.h>
+#endif
 
-#include <netinet/in_systm.h>
-#include <netinet/in.h>
-#include <netinet/ip.h>
-#include <netinet/ip_icmp.h>
-#ifdef HAVE_NETINET_IP_VAR_H
-# include <netinet/ip_var.h>
+#if TIME_WITH_SYS_TIME
+# include <sys/time.h>
+# include <time.h>
 #endif
 
-#include <netinet/ip6.h>
-#include <netinet/icmp6.h>
+#if HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
+#if HAVE_NETDB_H
+# include <netdb.h>
+#endif
 
-#include <sys/time.h>
-#include <time.h>
+#if HAVE_NETINET_IN_SYSTM_H
+# include <netinet/in_systm.h>
+#endif
+#if HAVE_NETINET_IN_H
+# include <netinet/in.h>
+#endif
+#if HAVE_NETINET_IP_H
+# include <netinet/ip.h>
+#endif
+#if HAVE_NETINET_IP_ICMP_H
+# include <netinet/ip_icmp.h>
+#endif
+#ifdef HAVE_NETINET_IP_VAR_H
+# include <netinet/ip_var.h>
+#endif
+#if HAVE_NETINET_IP6_H
+# include <netinet/ip6.h>
+#endif
+#if HAVE_NETINET_ICMP6_H
+# include <netinet/icmp6.h>
+#endif
 
 #include "liboping.h"
 
index 73d878c..065ae95 100644 (file)
 #ifndef OCTO_PING_H
 #define OCTO_PING_H 1
 
-#include <stdlib.h>
-#include <unistd.h>
+#if HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#if HAVE_STDLIB_H
+# include <stdlib.h>
+#endif
+#if HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+#if HAVE_SYS_SOCKET_H
+# include <sys/socket.h>
+#endif
 
 /*
  * Type definitions
index ecfd0ec..72ce930 100644 (file)
 #include "utils_debug.h"
 #include "utils_mount.h"
 
+#if HAVE_GETFSSTAT
+#  if HAVE_SYS_PARAM_H
+#    include <sys/param.h>
+#  endif
+#  if HAVE_SYS_UCRED_H
+#    include <sys/ucred.h>
+#  endif
+#  if HAVE_SYS_MOUNT_H
+#    include <sys/mount.h>
+#  endif
+#endif /* HAVE_GETMNTINFO */
+
+#if HAVE_MNTENT_H
+#  include <mntent.h>
+#endif
+#if HAVE_SYS_MNTTAB_H
+#  include <sys/mnttab.h>
+#endif
 
+#ifndef MNTTAB
+#  if defined(_PATH_MOUNTED)
+#    define MNTTAB _PATH_MOUNTED
+#  elif defined(MNT_MNTTAB)
+#    define MNTTAB MNT_MNTTAB
+#  elif defined(MNTTABNAME)
+#    define MNTTAB MNTTABNAME
+#  elif defined(KMTAB)
+#    define MNTTAB KMTAB
+#  else
+#    define MNTTAB "/etc/mnttab"
+#  endif
+#endif
 
 /* *** *** *** ********************************************* *** *** *** */
 /* *** *** *** *** *** ***   private functions   *** *** *** *** *** *** */
 /* *** *** *** ********************************************* *** *** *** */
 
-
-
 /* stolen from quota-3.13 (quota-tools) */
 
 #define PROC_PARTITIONS "/proc/partitions"
@@ -289,53 +318,54 @@ get_spec_by_uuid(const char *s)
        return NULL;
 }
 
-static char *
-get_spec_by_volume_label(const char *s)
+static char *get_spec_by_volume_label(const char *s)
 {
-        return get_spec_by_x(VOL, s);
+        return get_spec_by_x (VOL, s);
 }
 
-static char *
-get_device_name(const char *item)
+static char *get_device_name(const char *optstr)
 {
        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 (optstr == NULL)
+       {
+               return (NULL);
        }
-       if(!rc) {
-               DBG("Error checking device name: %s", item);
+       else if (strncmp (optstr, "UUID=", 5) == 0)
+       {
+               DBG ("TODO: check UUID= code!");
+               rc = get_spec_by_uuid (optstr + 5);
+       }
+       else if (strncmp (optstr, "LABEL=", 6) == 0)
+       {
+               DBG ("TODO: check LABEL= code!");
+               rc = get_spec_by_volume_label (optstr + 6);
+       }
+       else
+       {
+               rc = sstrdup (optstr);
        }
-       return rc;
-}
-
-
 
-#if HAVE_GETVFSENT
-static void
-cu_mount_getvfsmnt(FILE *mntf, cu_mount_t **list)
-{
-       DBG("TODO: getvfsmnt");
-       *list = NULL;
+       if(!rc)
+       {
+               DBG ("Error checking device name: optstr = %s", optstr);
+       }
+       return rc;
 }
-#endif /* HAVE_GETVFSENT */
 
-
-
-#if HAVE_LISTMNTENT
-static cu_mount_t *
-cu_mount_listmntent(struct tabmntent *mntlist, cu_mount_t **list)
+/* What weird OS is this..? I can't find any info with google :/ -octo */
+#if HAVE_LISTMNTENT && 0
+static cu_mount_t *cu_mount_listmntent (void)
 {
        cu_mount_t *last = *list;
        struct tabmntent *p;
        struct mntent *mnt;
 
+       struct tabmntent *mntlist;
+       if(listmntent(&mntlist, MNTTAB, NULL, NULL) < 0) {
+               DBG("calling listmntent() failed: %s", strerror(errno));
+       }
+
        for(p = mntlist; p; p = p->next) {
                char *loop = NULL, *device = NULL;
 
@@ -371,242 +401,240 @@ cu_mount_listmntent(struct tabmntent *mntlist, cu_mount_t **list)
        } /* for(p = mntlist; p; p = p->next) */
 
        return(last);
-} /* static cu_mount_t *cu_mount_listmntent(struct tabmntent *mntlist,
-       cu_mount_t **list) */
-#endif /* HAVE_LISTMNTENT */
+} /* cu_mount_t *cu_mount_listmntent(void) */
+/* #endif HAVE_LISTMNTENT */
 
+/* 4.4BSD and Mac OS X */
+#elif HAVE_GETFSSTAT
+static cu_mount_t *cu_mount_getfsstat (void)
+{
+       int bufsize;
+       struct statfs *buf;
 
+       int num;
+       int i;
 
-#if HAVE_GETMNTENT
-static cu_mount_t *
-cu_mount_getmntent(FILE *mntf, cu_mount_t **list)
-{
-       cu_mount_t *last = *list;
-#if HAVE_GETMNTENT1
-       struct mntent *mnt = NULL;
-#endif
-#if HAVE_GETMNTENT2
-       struct mntent real_mnt;
-       struct mntent *mnt = &real_mnt;
-#endif
+       cu_mount_t *first = NULL;
+       cu_mount_t *last  = NULL;
+       cu_mount_t *new   = NULL;
 
-#if HAVE_GETMNTENT1
-       while((mnt = getmntent(mntf)) != NULL) {
-#endif
-#if HAVE_GETMNTENT2
-       while(getmntent(mntf, &real_mnt) == 0) {
-#endif
-               char *loop = NULL, *device = NULL;
+       /* Get the number of mounted file systems */
+       if ((bufsize = getfsstat (NULL, 0, MNT_NOWAIT)) < 1)
+               return (NULL);
 
-#if 0
-               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
+       if ((buf = (struct statfs *) malloc (bufsize * sizeof (struct statfs))) == NULL)
+               return (NULL);
+       memset (buf, '\0', bufsize * sizeof (struct statfs));
 
-               loop = cu_mount_getoptionvalue(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;
-               }
+       /* FIXME: If `bufsize' in bytes or structures? */
+       if ((num = getfsstat (buf, bufsize, MNT_NOWAIT)) < 1)
+       {
+               free (buf);
+               return (NULL);
+       }
 
-#if 0
-               DBG("device: %s", device);
-               DBG("------------------ END");
-#endif
-               if(*list == NULL) {
-                       *list = (cu_mount_t *)smalloc(sizeof(cu_mount_t));
-                       last = *list;
-               } else {
-                       while(last->next != NULL) { /* is last really last? */
-                               last = last->next;
-                       }
-                       last->next = (cu_mount_t *)smalloc(sizeof(cu_mount_t));
-                       last = last->next;
+       for (i = 0; i < num; i++)
+       {
+               if ((new = malloc (sizeof (cu_mount_t))) == NULL)
+                       break;
+               memset (new, '\0', sizeof (cu_mount_t));
+               
+               /* Copy values from `struct mnttab' */
+               new->dir         = sstrdup (buf[i].f_mntonname);
+               new->spec_device = sstrdup (buf[i].f_mntfromname);
+               new->type        = sstrdup (buf[i].f_fstypename);
+               new->options     = NULL;
+               new->device      = get_device_name (new->options);
+               new->next = NULL;
+
+               /* Append to list */
+               if (first == NULL)
+               {
+                       first = new;
+                       last  = new;
                }
-               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;
-#if HAVE_GETMNTENT2
-       } /* while(getmntent(mntf, &real_mnt) == 0) */
-#endif
-#if HAVE_GETMNTENT1
-       } /* while((mnt = getmntent(mntf)) != NULL) */
-#endif
+               else
+               {
+                       last->next = new;
+                       last       = new;
+               }
+       }
 
-       return last;
-} /* static cu_mount_t *cu_mount_getmntent(FILE *mntf, cu_mount_t **list) */
-#endif /* HAVE_GETMNTENT */
+       free (buf);
 
+       return (first);
+}
+/* #endif HAVE_GETFSSTAT */
 
+/* Solaris (SunOS 10): int getmntent(FILE *fp, struct mnttab *mp); */
+#elif HAVE_GEN_GETMNTENT
+static cu_mount_t *cu_mount_gen_getmntent (void)
+{
+       struct mnttab mt;
+       FILE *fp;
 
-/* *** *** *** ******************************************** *** *** *** */
-/* *** *** *** *** *** ***   public functions   *** *** *** *** *** *** */
-/* *** *** *** ******************************************** *** *** *** */
+       cu_mount_t *first = NULL;
+       cu_mount_t *last  = NULL;
+       cu_mount_t *new   = NULL;
 
+       if ((fp = fopen (MNTTAB, "r")) == NULL)
+               return (NULL);
 
+       while (getmntent (fp, &mt) == 0)
+       {
+               if ((new = malloc (sizeof (cu_mount_t))) == NULL)
+                       break;
+               memset (new, '\0', sizeof (cu_mount_t));
+               
+               /* Copy values from `struct mnttab' */
+               new->dir         = sstrdup (mt.mnt_mountp);
+               new->spec_device = sstrdup (mt.mnt_special);
+               new->type        = sstrdup (mt.mnt_fstype);
+               new->options     = sstrdup (mt.mnt_mntopts);
+               new->device      = get_device_name (new->options);
+               new->next = NULL;
+
+               /* Append to list */
+               if (first == NULL)
+               {
+                       first = new;
+                       last  = new;
+               }
+               else
+               {
+                       last->next = new;
+                       last       = new;
+               }
+       }
+
+       fclose (fp);
+
+       return (first);
+} /* static cu_mount_t *cu_mount_gen_getmntent (void) */
+/* #endif HAVE_GEN_GETMNTENT */
+
+#elif HAVE_SEQ_GETMNTENT
+#warn "This version of `getmntent' hat not yet been implemented!"
+/* #endif HAVE_SEQ_GETMNTENT */
 
-cu_mount_t *
-cu_mount_getlist(cu_mount_t **list)
+#elif HAVE_SUN_GETMNTENT
+#warn "This version of `getmntent' hat not yet been implemented!"
+/* #endif HAVE_SUN_GETMNTENT */
+
+#elif HAVE_GETMNTENT
+static cu_mount_t *cu_mount_getmntent (void)
 {
-       cu_mount_t *last = NULL;
-
-       /* see lib/mountlist.c of coreutils for all (ugly) details! */
-
-/*
-   there are two implementations of getmntent():
-     * one argument getmntent:
-           FILE *setmntent(const char *filename, const char *type);
-           struct mntent *getmntent(FILE *fp);
-           int endmntent(FILE *fp);
-     * two argument getmntent:
-           FILE *fopen(const char *path, const char *mode);
-           int getmntent(FILE *fp, struct mnttab *mnt);
-           int fclose(FILE *fp);
-   and a third (linux/gnu style) version called getmntent_r, which is not used
-   here (enough trouble with the two versions above).
-*/
-#if HAVE_GETMNTENT
-# if HAVE_GETMNTENT1
-#  define setmntent setmntent
-#  define endmntent endmntent
-# else
-#  if HAVE_GETMNTENT2
-#   define setmntent fopen
-#   define endmntent fclose
-#  else
-#   error HAVE_GETMNTENT defined, but neither HAVE_GETMNTENT1 nor HAVE_GETMNTENT2
-#  endif /* HAVE_GETMNTENT2 */
-# endif /* HAVE_GETMNTENT1 */
-#endif /* HAVE_GETMNTENT */
+       FILE *fp;
+       struct mntent *me;
 
-       /* the indentation is wrong. is there a better way to do this? */
+       cu_mount_t *first = NULL;
+       cu_mount_t *last  = NULL;
+       cu_mount_t *new   = NULL;
 
-#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_LISTMNTENT
-       {
-       struct tabmntent *mntlist;
-       if(listmntent(&mntlist, KMTAB, NULL, NULL) < 0) {
-               DBG("calling listmntent() failed: %s", strerror(errno));
-#endif
-#if HAVE_GETVFSENT && defined(VFSTAB)
-       /* this is as bad as the next one, read next comment */
-       {
-       FILE *mntf = NULL;
-       if((mntf = fopen(VFSTAB, "r")) == NULL) {
-               DBG("opening %s failed: %s", VFSTAB, strerror(errno));
-#endif
-#if HAVE_GETMNTENT && defined(_PATH_MNTTAB)
-       /* _PATH_MNTTAB is usually /etc/fstab and so this should be really
-          the very last thing to try, because it does not provide a list
-          of currently mounted filesystems... */
+       if ((fp = setmntent (MNTTAB, "r")) == NULL)
+               return (NULL);
+
+       while ((me = getmntent (fp)) != NULL)
        {
-       FILE *mntf = NULL;
-       if((mntf = setmntent(_PATH_MNTTAB, "r")) == NULL) {
-               DBG("opening %s failed: %s", _PATH_MNTTAB, strerror(errno));
-#endif
+               if ((new = malloc (sizeof (cu_mount_t))) == NULL)
+                       break;
+               memset (new, '\0', sizeof (cu_mount_t));
+               
+               /* Copy values from `struct mntent *' */
+               new->dir         = sstrdup (me->mnt_dir);
+               new->spec_device = sstrdup (me->mnt_fsname);
+               new->type        = sstrdup (me->mnt_type);
+               new->options     = sstrdup (me->mnt_opts);
+               new->device      = get_device_name (new->options);
+               new->next        = NULL;
+
+               /* Append to list */
+               if (first == NULL)
+               {
+                       first = new;
+                       last  = new;
+               }
+               else
+               {
+                       last->next = new;
+                       last       = new;
+               }
+       }
 
-       /* give up */
-       DBG("failed get local mountpoints");
-       return(NULL);
+       endmntent (fp);
 
-#if HAVE_GETMNTENT && defined(_PATH_MNTTAB)
-       } else { last = cu_mount_getmntent(mntf, list); }
-       (void)endmntent(mntf);
-       }
-#endif
-#if HAVE_GETVFSENT && defined(VFSTAB)
-       } else { last = cu_mount_getvfsmnt(mntf, list); }
-       (void)fclose(mntf);
-       }
-#endif
-#if HAVE_LISTMNTENT
-       } else { last = cu_mount_listmntent(mntlist, list); }
-       freemntlist(mntlist);
-       }
-#endif
-#if HAVE_GETMNTENT && defined(MNTTABNAME)
-       } else { last = cu_mount_getmntent(mntf, list); }
-       (void)endmntent(mntf);
+       return (first);
+}
+#endif /* HAVE_GETMNTENT */
+
+/* *** *** *** ******************************************** *** *** *** */
+/* *** *** *** *** *** ***   public functions   *** *** *** *** *** *** */
+/* *** *** *** ******************************************** *** *** *** */
+
+cu_mount_t *cu_mount_getlist(cu_mount_t **list)
+{
+       cu_mount_t *new;
+       cu_mount_t *first = NULL;
+       cu_mount_t *last  = NULL;
+
+       if (list == NULL)
+               return (NULL);
+
+       if (*list != NULL)
+       {
+               first = *list;
+               last  =  first;
+               while (last->next != NULL)
+                       last = last->next;
        }
+
+#if HAVE_LISTMNTENT && 0
+       new = cu_mount_listmntent ();
+#elif HAVE_GETFSSTAT
+       new = cu_mount_getfsstat ();
+#elif HAVE_GEN_GETMNTENT
+       new = cu_mount_gen_getmntent ();
+#elif HAVE_GETMNTENT
+       new = cu_mount_getmntent ();
+#else
+       new = NULL;
 #endif
-#if HAVE_GETMNTENT && defined(MNT_MNTTAB)
-       } else { last = cu_mount_getmntent(mntf, list); }
-       (void)endmntent(mntf);
+
+       if (first != NULL)
+       {
+               last->next = new;
        }
-#endif
-#if HAVE_GETMNTENT && defined(_PATH_MOUNTED)
-       } else { last = cu_mount_getmntent(mntf, list); }
-       (void)endmntent(mntf);
+       else
+       {
+               first = new;
+               last  = new;
+               *list = first;
        }
-#endif
-       return(last);
-} /* cu_mount_t *cu_mount_getlist(cu_mount_t **list) */
 
+       while ((last != NULL) && (last->next != NULL))
+               last = last->next;
 
+       return (last);
+} /* cu_mount_t *cu_mount_getlist(cu_mount_t **list) */
 
-void
-cu_mount_freelist(cu_mount_t *list)
+void cu_mount_freelist (cu_mount_t *list)
 {
-       cu_mount_t *l = list, *p = NULL;
+       cu_mount_t *this;
+       cu_mount_t *next;
 
-       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);
-               p = NULL;
-               if(l != list) {
-                       sfree(l);
-                       l = list;
-               } else {
-                       sfree(l);
-                       l = NULL; /* done by sfree already */
-               }
-       } /* while(l != NULL) */
+       for (this = list; this != NULL; this = next)
+       {
+               next = this->next;
+
+               sfree (this->dir);
+               sfree (this->spec_device);
+               sfree (this->device);
+               sfree (this->type);
+               sfree (this->options);
+               sfree (this);
+       }
 } /* void cu_mount_freelist(cu_mount_t *list) */
 
-
-
 char *
 cu_mount_checkoption(char *line, char *keyword, int full)
 {
@@ -647,8 +675,6 @@ cu_mount_checkoption(char *line, char *keyword, int full)
        return NULL;
 } /* char *cu_mount_checkoption(char *line, char *keyword, int full) */
 
-
-
 char *
 cu_mount_getoptionvalue(char *line, char *keyword)
 {