#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <fnmatch.h>
#include <apr_general.h>
#include <apr_strings.h>
#include "hostinfod.h"
typedef int (*process_line_fn) (const char *path, int lineno,
- const char *key, const char *value);
+ const char *key, const char *value,
+ void *data);
typedef int (*process_section_fn) (const char *path, int lineno,
- const char *section);
+ const char *section,
+ void *data);
static void process_conf_file (const char *path, int exit_if_not_exist,
process_line_fn process_line,
- process_section_fn process_section);
+ process_section_fn process_section,
+ void *data);
static int get_bool (const char *str);
/* Read the main configuration file. */
-static int main_process_line (const char *path, int lineno, const char *key, const char *value);
+static int main_process_line (const char *path, int lineno, const char *key, const char *value, void *data);
void
read_main_conf_file (void)
{
- process_conf_file (conf_file, 0, main_process_line, NULL);
+ process_conf_file (conf_file, 0, main_process_line, NULL, NULL);
}
static int
main_process_line (const char *path, int lineno,
- const char *key, const char *value)
+ const char *key, const char *value,
+ void *data)
{
int bool;
return -1;
}
socket_dir = apr_pstrdup (pool, value);
+ } else if (strcasecmp (key, "libvirt") == 0) {
+ if (!value) {
+ error ("%s:%d: directive is empty: %s", path, lineno, key);
+ return -1;
+ }
+ if (!libvirt_uri_set_on_cmdline)
+ libvirt_uri = apr_pstrdup (pool, value);
} else if (strcasecmp (key, "verbose") == 0) {
bool = get_bool (value);
if (bool == -1) {
return 0;
}
+/* Check that 'cmd' is enabled for the named guest, and that
+ * it is not being called too frequently.
+ *
+ * XXX Rereading the configuration file each time is possibly
+ * inefficient.
+ *
+ * Returns 0 = proceed, -1 = fail.
+ */
+static int guests_process_line (const char *path, int lineno,
+ const char *key, const char *value,
+ void *data);
+static int guests_process_section (const char *path, int lineno,
+ const char *section,
+ void *data);
+
+struct guests_data {
+ const char *name; /* guest "driver-name" */
+ const char *cmd; /* command being tested */
+ int in_section; /* currently processing the right section? */
+ double interval; /* interval for this guest (0 = any) */
+ int enabled; /* is command enabled? */
+};
+
+void
+check_guests_file (struct guest_description *hval, const char *cmd,
+ double *interval, int *enabled)
+{
+ struct guests_data *data = apr_palloc (hval->rpool, sizeof *data);
+
+ data->name = hval->name;
+ data->cmd = cmd;
+ data->in_section = 0;
+ data->interval = 60.; /* default */
+ data->enabled = 0; /* default */
+
+ process_conf_file (guests_file, 1,
+ guests_process_line, guests_process_section, data);
+
+ *interval = data->interval;
+ *enabled = data->enabled;
+}
+
+static int
+guests_process_line (const char *path, int lineno,
+ const char *key, const char *value,
+ void *datav)
+{
+ struct guests_data *data = datav;
+ int bool;
+
+ if (!data->in_section)
+ return 0;
+
+ if (strcasecmp (key, "interval") == 0) {
+ if (strcasecmp (value, "any") == 0)
+ data->interval = 0;
+ else {
+ if (sscanf (value, "%lg", &data->interval) != 1) {
+ error ("%s:%d: %s: not a valid decimal number", path, lineno, key);
+ return -1;
+ }
+ }
+ } else if (strcasecmp (key, data->cmd) == 0) {
+ bool = get_bool (value);
+ if (bool == -1) {
+ error ("%s:%d: %s: not a valid boolean - use 1 or 0", path, lineno, key);
+ return -1;
+ }
+ data->enabled = bool;
+ }
+
+ return 0;
+}
+
+static int
+guests_process_section (const char *path, int lineno,
+ const char *section,
+ void *datav)
+{
+ struct guests_data *data = datav;
+ int flags = 0;
+
+#ifdef FNM_CASEFOLD
+ flags |= FNM_CASEFOLD;
+#endif
+
+ data->in_section = fnmatch (section, data->name, flags) == 0;
+ return 0;
+}
+
/* Configuration file parser. */
static void
process_conf_file (const char *path, int exit_if_not_exist,
process_line_fn process_line,
- process_section_fn process_section)
+ process_section_fn process_section,
+ void *data)
{
static const char *whitespace = " \t\n\v";
FILE *fp;
exit (1);
}
- debug ("configuration file: section [%s]", line);
+ debug ("configuration file: section [%s]", &line[1]);
if (!process_section) {
error ("%s:%d: unexpected section header ([%s]) in file",
- path, lineno, line);
+ path, lineno, &line[1]);
exit (1);
}
- if (process_section (path, lineno, line) == -1)
+ if (process_section (path, lineno, &line[1], data) == -1)
exit (1);
}
else { /* Key value */
key = line;
value = key_len < real_len ? &line[key_len+1] : NULL;
if (value) {
- value += strspn (line, whitespace);
+ value += strspn (value, whitespace);
if (value[0] == '\0')
value = NULL;
}
debug ("configuration file: key '%s', value '%s'", key, value);
- if (process_line && process_line (path, lineno, key, value) == -1)
+ if (process_line && process_line (path, lineno, key, value, data) == -1)
exit (1);
}
}