src/configfile.c: Use wordexp(3) to expand shell wildcards if available.
authorFlorian Forster <octo@leeloo.lan.home.verplant.org>
Mon, 11 Feb 2008 11:01:06 +0000 (12:01 +0100)
committerFlorian Forster <octo@leeloo.lan.home.verplant.org>
Mon, 11 Feb 2008 11:01:06 +0000 (12:01 +0100)
configure.in
src/configfile.c

index 04ba0f8..f59fc6b 100644 (file)
@@ -311,7 +311,7 @@ AC_CHECK_HEADERS(linux/un.h, [], [],
 #endif
 ])
 
-AC_CHECK_HEADERS(pwd.h grp.h sys/un.h ctype.h limits.h sys/quota.h xfs/xqm.h fs_info.h fshelp.h paths.h mntent.h mnttab.h sys/fstyp.h sys/fs_types.h sys/mntent.h sys/mnttab.h sys/statfs.h sys/statvfs.h sys/vfs.h sys/vfstab.h kvm.h)
+AC_CHECK_HEADERS(pwd.h grp.h sys/un.h ctype.h limits.h sys/quota.h xfs/xqm.h fs_info.h fshelp.h paths.h mntent.h mnttab.h sys/fstyp.h sys/fs_types.h sys/mntent.h sys/mnttab.h sys/statfs.h sys/statvfs.h sys/vfs.h sys/vfstab.h kvm.h wordexp.h)
 
 # For the dns plugin
 AC_CHECK_HEADERS(arpa/nameser.h)
index 3b6cb6b..36b6dad 100644 (file)
 #include "types_list.h"
 #include "utils_threshold.h"
 
+#if HAVE_WORDEXP_H
+# include <wordexp.h>
+#endif /* HAVE_WORDEXP_H */
+
 #define ESCAPE_NULL(str) ((str) == NULL ? "(null)" : (str))
 
 /*
@@ -546,11 +550,20 @@ static oconfig_item_t *cf_read_dir (const char *dir, int depth)
  *
  * Path is stat'ed and either cf_read_file or cf_read_dir is called
  * accordingly.
+ *
+ * There are two versions of this function: If `wordexp' exists shell wildcards
+ * will be expanded and the function will include all matches found. If
+ * `wordexp' (or, more precisely, it's header file) is not available the
+ * simpler function is used which does not do any such expansion.
  */
+#if HAVE_WORDEXP_H
 static oconfig_item_t *cf_read_generic (const char *path, int depth)
 {
-       struct stat statbuf;
+       oconfig_item_t *root = NULL;
        int status;
+       const char *path_ptr;
+       wordexp_t we;
+       int i;
 
        if (depth >= CF_MAX_DEPTH)
        {
@@ -559,7 +572,72 @@ static oconfig_item_t *cf_read_generic (const char *path, int depth)
                return (NULL);
        }
 
-       fprintf (stderr, "cf_read_generic (path = %s, depth = %i);", path, depth);
+       status = wordexp (path, &we, WRDE_NOCMD);
+       if (status != 0)
+       {
+               ERROR ("configfile: wordexp (%s) failed.", path);
+               return (NULL);
+       }
+
+       root = (oconfig_item_t *) malloc (sizeof (oconfig_item_t));
+       if (root == NULL)
+       {
+               ERROR ("configfile: malloc failed.");
+               return (NULL);
+       }
+       memset (root, '\0', sizeof (oconfig_item_t));
+
+       for (i = 0; i < we.we_wordc; i++)
+       {
+               oconfig_item_t *temp;
+               struct stat statbuf;
+
+               path_ptr = we.we_wordv[i];
+
+               status = stat (path_ptr, &statbuf);
+               if (status != 0)
+               {
+                       char errbuf[1024];
+                       ERROR ("configfile: stat (%s) failed: %s",
+                                       path_ptr,
+                                       sstrerror (errno, errbuf, sizeof (errbuf)));
+                       return (NULL);
+               }
+
+               if (S_ISREG (statbuf.st_mode))
+                       temp = cf_read_file (path_ptr, depth);
+               else if (S_ISDIR (statbuf.st_mode))
+                       temp = cf_read_dir (path_ptr, depth);
+               else
+               {
+                       ERROR ("configfile: %s is neither a file nor a "
+                                       "directory.", path);
+                       continue;
+               }
+
+               cf_ci_append_children (root, temp);
+               sfree (temp->children);
+               sfree (temp);
+       }
+
+       wordfree (&we);
+
+       return (root);
+} /* oconfig_item_t *cf_read_generic */
+/* #endif HAVE_WORDEXP_H */
+
+#else /* if !HAVE_WORDEXP_H */
+static oconfig_item_t *cf_read_generic (const char *path, int depth)
+{
+       struct stat statbuf;
+       int status;
+
+       if (depth >= CF_MAX_DEPTH)
+       {
+               ERROR ("configfile: Not including `%s' because the maximum "
+                               "nesting depth has been reached.", path);
+               return (NULL);
+       }
 
        status = stat (path, &statbuf);
        if (status != 0)
@@ -579,6 +657,7 @@ static oconfig_item_t *cf_read_generic (const char *path, int depth)
        ERROR ("configfile: %s is neither a file nor a directory.", path);
        return (NULL);
 } /* oconfig_item_t *cf_read_generic */
+#endif /* !HAVE_WORDEXP_H */
 
 /* 
  * Public functions