This patch adds the files implements dnsmasq (hostsfile) module.
Signed-off-by: Satoru SATOH <satoru.satoh(a)gmail.com>
---
src/util/dnsmasq.c | 296 ++++++++++++++++++++++++++++++++++++++++++++++++++++
src/util/dnsmasq.h | 54 ++++++++++
2 files changed, 350 insertions(+), 0 deletions(-)
create mode 100644 src/util/dnsmasq.c
create mode 100644 src/util/dnsmasq.h
diff --git a/src/util/dnsmasq.c b/src/util/dnsmasq.c
new file mode 100644
index 0000000..8760c7c
--- /dev/null
+++ b/src/util/dnsmasq.c
@@ -0,0 +1,296 @@
+/*
+ * Copyright (C) 2010 Satoru SATOH <satoru.satoh(a)gmail.com>
+ * Copyright (C) 2007-2009 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * Based on iptables.c
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+#include <limits.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <signal.h>
+
+#ifdef HAVE_PATHS_H
+#include <paths.h>
+#endif
+
+#include "internal.h"
+#include "dnsmasq.h"
+#include "util.h"
+#include "memory.h"
+#include "virterror_internal.h"
+#include "logging.h"
+
+static void
+hostsfileFree(dnsmasqHostfile *hostsfile)
+{
+ int i;
+
+ if (hostsfile->entries) {
+ for (i = 0; i < hostsfile->nentries; i++)
+ VIR_FREE(hostsfile->entries[i].entry);
+
+ VIR_FREE(hostsfile->entries);
+
+ hostsfile->nentries = 0;
+ }
+
+ hostsfile->path[0] = '\0';
+
+ VIR_FREE(hostsfile);
+}
+
+static dnsmasqHostfile *
+hostsfileNew(const char *name,
+ const char *config_dir)
+{
+ int err;
+ char ebuf[1024];
+
+ dnsmasqHostfile *hostsfile;
+
+ if (VIR_ALLOC(hostsfile) < 0)
+ return NULL;
+
+ hostsfile->entries = NULL;
+ hostsfile->nentries = 0;
+
+ if ((err = virFileMakePath(config_dir))) {
+ VIR_WARN(_("Failed to create directory %s : %s"), config_dir,
+ virStrerror(err, ebuf, sizeof ebuf));
+ goto error;
+ }
+
+ if (virFileBuildPath(config_dir, name, ".hostsfile", hostsfile->path,
+ sizeof(hostsfile->path)) < 0)
+ goto error;
+
+ return hostsfile;
+
+ error:
+ hostsfileFree(hostsfile);
+ return NULL;
+}
+
+static int
+hostsfileAdd(dnsmasqHostfile *hostsfile,
+ const char *mac,
+ const char *ip,
+ const char *name)
+{
+ if (VIR_REALLOC_N(hostsfile->entries, hostsfile->nentries+1) < 0)
+ return ENOMEM;
+
+ if (virAsprintf(&hostsfile->entries[hostsfile->nentries].entry,
+ "%s,%s,%s", mac, name, ip) < 0) {
+ return ENOMEM;
+ }
+
+ hostsfile->nentries++;
+
+ return 0;
+}
+
+static int
+hostsfileWrite(const char *path,
+ const dhcpHostEntry *entries,
+ int nentries)
+{
+ char tmp[PATH_MAX];
+ FILE *f;
+ int istmp;
+ int i;
+
+ if (nentries == 0 && unlink(path) == 0)
+ return 0;
+
+ if (snprintf(tmp, PATH_MAX, "%s.new", path) >= PATH_MAX)
+ return EINVAL;
+
+ istmp = 1;
+
+ if (!(f = fopen(tmp, "w"))) {
+ istmp = 0;
+ if (!(f = fopen(path, "w")))
+ return errno;
+ }
+
+ for (i = 0; i < nentries; i++) {
+ if (fputs(entries[i].entry, f) == EOF ||
+ fputc('\n', f) == EOF) {
+ fclose(f);
+ if (istmp)
+ unlink(tmp);
+ return errno;
+ }
+ }
+
+ fclose(f);
+
+ if (istmp && rename(tmp, path) < 0) {
+ unlink(tmp);
+ return errno;
+ }
+
+ if (istmp)
+ unlink(tmp);
+
+ return 0;
+}
+
+static int
+hostsfileSave(const dnsmasqContext *ctx)
+{
+ if (hostsfileWrite(ctx->hostsfile->path, ctx->hostsfile->entries,
+ ctx->hostsfile->nentries) < 0) {
+ VIR_WARN(_("cannot write config file '%s'\n"),
ctx->hostsfile->path);
+ return -1;
+ }
+
+ return 0;
+}
+
+static int
+hostsfileDelete(const dnsmasqContext *ctx)
+{
+ if (! virFileExists(ctx->hostsfile->path))
+ return 0;
+
+ if (unlink(ctx->hostsfile->path) < 0) {
+ VIR_WARN(_("cannot remove config file '%s'\n"),
ctx->hostsfile->path);
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ * dnsmasqContextNew:
+ *
+ * Create a new Dnsmasq context
+ *
+ * Returns a pointer to the new structure or NULL in case of error
+ */
+dnsmasqContext *
+dnsmasqContextNew(const char *network_name,
+ const char *config_dir)
+{
+ dnsmasqContext *ctx;
+
+ if (VIR_ALLOC(ctx) < 0)
+ return NULL;
+
+ if (!(ctx->hostsfile = hostsfileNew(network_name, config_dir)))
+ goto error;
+
+ return ctx;
+
+ error:
+ dnsmasqContextFree(ctx);
+ return NULL;
+}
+
+/**
+ * dnsmasqContextFree:
+ * @ctx: pointer to the dnsmasq context
+ *
+ * Free the resources associated with an dnsmasq context
+ */
+void
+dnsmasqContextFree(dnsmasqContext *ctx)
+{
+ if (ctx->hostsfile)
+ hostsfileFree(ctx->hostsfile);
+ VIR_FREE(ctx);
+}
+
+/**
+ * dnsmasqAddDhcpHost:
+ * @ctx: pointer to the dnsmasq context for each network
+ * @mac: pointer to the string contains mac address of the host
+ * @ip: pointer to the string contains ip address of the host
+ * @name: pointer to the string contains hostname of the host
+ *
+ * Add host entries.
+ */
+void
+dnsmasqAddDhcpHost(dnsmasqContext *ctx,
+ const char *mac,
+ const char *ip,
+ const char *name)
+{
+ if (hostsfileAdd(ctx->hostsfile, mac, ip, name))
+ VIR_WARN(_("Failed to add host: mac=%s, ip=%s, name=%s\n"), mac, ip,
name);
+}
+
+/**
+ * dnsmasqSave:
+ * @ctx: pointer to the dnsmasq context for each network
+ *
+ * Saves all the configurations associated with a context to disk.
+ */
+int
+dnsmasqSave(const dnsmasqContext *ctx)
+{
+ if (hostsfileSave(ctx) < 0)
+ return 0;
+
+ return 1;
+}
+
+
+/**
+ * dnsmasqDelete:
+ * @ctx: pointer to the dnsmasq context for each network
+ *
+ * Delete all the configuration files associated with a context.
+ */
+int
+dnsmasqDelete(const dnsmasqContext *ctx)
+{
+ if (hostsfileDelete(ctx) < 0)
+ return 0;
+
+ return 1;
+}
+
+/**
+ * dnsmasqReload:
+ * @ctx: pointer to the dnsmasq context
+ *
+ * Reloads all the configurations associated to a context
+ */
+int
+dnsmasqReload(pid_t pid)
+{
+ if (kill(pid, SIGHUP) != 0) {
+ VIR_WARN(_("Failed to make dnsmasq (PID: %d) reloading config
files.\n"), pid);
+ return 0;
+ }
+
+ return 1;
+}
+
diff --git a/src/util/dnsmasq.h b/src/util/dnsmasq.h
new file mode 100644
index 0000000..4343ed9
--- /dev/null
+++ b/src/util/dnsmasq.h
@@ -0,0 +1,54 @@
+/*
+ * Copyright (C) 2010 Satoru SATOH <satoru.satoh(a)gmail.com>
+ * Copyright (C) 2007, 2008 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ * based on iptables.h
+ */
+
+#ifndef __DNSMASQ_H__
+#define __DNSMASQ_H__
+
+typedef struct
+{
+ char *entry; /* "<mac>,<hostname>,<ip>", ex.
"01:23:45:67:89:0a,foo,10.0.0.3" */
+} dhcpHostEntry;
+
+typedef struct
+{
+ int nentries;
+ dhcpHostEntry *entries;
+
+ char path[PATH_MAX];
+} dnsmasqHostfile;
+
+typedef struct
+{
+ dnsmasqHostfile *hostsfile;
+} dnsmasqContext;
+
+dnsmasqContext * dnsmasqContextNew(const char *network_name,
+ const char *config_dir);
+void dnsmasqContextFree(dnsmasqContext *ctx);
+void dnsmasqAddDhcpHost(dnsmasqContext *ctx,
+ const char *mac,
+ const char *ip,
+ const char *name);
+int dnsmasqSave(const dnsmasqContext *ctx);
+int dnsmasqDelete(const dnsmasqContext *ctx);
+int dnsmasqReload(pid_t pid);
+
+#endif /* __DNSMASQ_H__ */
--
1.6.6.1