[collectd] [PATCH] configfile.c: Include more than one files in lexicographical order.
Sebastian Harl
sh at tokkee.org
Thu Mar 20 13:22:15 CET 2008
Using qsort() and strcmp() the list of files (after reading the contents
of a directory or expanding globs) is sorted before inclusion. As the
order of options in the config file matters this is more convenient.
Signed-off-by: Sebastian Harl <sh at tokkee.org>
---
src/collectd.conf.pod | 5 ++++
src/configfile.c | 54 ++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 56 insertions(+), 3 deletions(-)
diff --git a/src/collectd.conf.pod b/src/collectd.conf.pod
index 7afe3f1..00f56e7 100644
--- a/src/collectd.conf.pod
+++ b/src/collectd.conf.pod
@@ -63,6 +63,11 @@ use statements like the following:
Include "/etc/collectd.d/*.conf"
+If more than one files are included by a single B<Include> option, the files
+will be included in lexicographical order (as defined by the C<strcmp>
+function). Thus, you can e.E<nbsp>g. use numbered prefixes to specify the
+order in which the files are loaded.
+
To prevent loops and shooting yourself in the foot in interesting ways the
nesting is limited to a depth of 8E<nbsp>levels, which should be sufficient for
most uses. Since symlinks are followed it is still possible to crash the daemon
diff --git a/src/configfile.c b/src/configfile.c
index 63b926a..e4f26d2 100644
--- a/src/configfile.c
+++ b/src/configfile.c
@@ -18,6 +18,7 @@
*
* Authors:
* Florian octo Forster <octo at verplant.org>
+ * Sebastian tokkee Harl <sh at tokkee.org>
**/
#include "collectd.h"
@@ -505,13 +506,20 @@ static oconfig_item_t *cf_read_file (const char *file, int depth)
return (root);
} /* oconfig_item_t *cf_read_file */
+static int cf_compare_string (const void *p1, const void *p2)
+{
+ return strcmp (*(const char **) p1, *(const char **) p2);
+}
+
static oconfig_item_t *cf_read_dir (const char *dir, int depth)
{
oconfig_item_t *root = NULL;
DIR *dh;
struct dirent *de;
- char name[1024];
+ char **filenames = NULL;
+ int filenames_num = 0;
int status;
+ int i;
assert (depth < CF_MAX_DEPTH);
@@ -534,7 +542,8 @@ static oconfig_item_t *cf_read_dir (const char *dir, int depth)
while ((de = readdir (dh)) != NULL)
{
- oconfig_item_t *temp;
+ char name[1024];
+ char **tmp;
if ((de->d_name[0] == '.') || (de->d_name[0] == '\0'))
continue;
@@ -546,12 +555,43 @@ static oconfig_item_t *cf_read_dir (const char *dir, int depth)
ERROR ("configfile: Not including `%s/%s' because its"
" name is too long.",
dir, de->d_name);
- oconfig_free (root);
+ for (i = 0; i < filenames_num; ++i)
+ free (filenames[i]);
+ free (filenames);
+ free (root);
+ return (NULL);
+ }
+
+ ++filenames_num;
+ tmp = (char **) realloc (filenames,
+ filenames_num * sizeof (*filenames));
+ if (tmp == NULL) {
+ ERROR ("configfile: realloc failed.");
+ for (i = 0; i < filenames_num - 1; ++i)
+ free (filenames[i]);
+ free (filenames);
+ free (root);
return (NULL);
}
+ filenames = tmp;
+
+ filenames[filenames_num - 1] = sstrdup (name);
+ }
+
+ qsort ((void *) filenames, filenames_num, sizeof (*filenames),
+ cf_compare_string);
+
+ for (i = 0; i < filenames_num; ++i)
+ {
+ oconfig_item_t *temp;
+ char *name = filenames[i];
temp = cf_read_generic (name, depth);
if (temp == NULL) {
+ int j;
+ for (j = i; j < filenames_num; ++j)
+ free (filenames[j]);
+ free (filenames);
oconfig_free (root);
return (NULL);
}
@@ -559,8 +599,11 @@ static oconfig_item_t *cf_read_dir (const char *dir, int depth)
cf_ci_append_children (root, temp);
sfree (temp->children);
sfree (temp);
+
+ free (name);
}
+ free(filenames);
return (root);
} /* oconfig_item_t *cf_read_dir */
@@ -606,6 +649,11 @@ static oconfig_item_t *cf_read_generic (const char *path, int depth)
}
memset (root, '\0', sizeof (oconfig_item_t));
+ /* wordexp() might return a sorted list already. That's not
+ * documented though, so let's make sure we get what we want. */
+ qsort ((void *) we.we_wordv, we.we_wordc, sizeof (*we.we_wordv),
+ cf_compare_string);
+
for (i = 0; i < we.we_wordc; i++)
{
oconfig_item_t *temp;
--
1.5.4.3.325.g6d216
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Digital signature
Url : http://mailman.verplant.org/pipermail/collectd/attachments/20080320/1a30ae87/attachment.pgp
More information about the collectd
mailing list