summaryrefslogtreecommitdiff
path: root/src/dumm/dumm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/dumm/dumm.c')
-rw-r--r--src/dumm/dumm.c157
1 files changed, 123 insertions, 34 deletions
diff --git a/src/dumm/dumm.c b/src/dumm/dumm.c
index 7ec340089..8cd413519 100644
--- a/src/dumm/dumm.c
+++ b/src/dumm/dumm.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008 Tobias Brunner
+ * Copyright (C) 2008-2009 Tobias Brunner
* Copyright (C) 2007 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -128,51 +128,145 @@ static void delete_bridge(private_dumm_t *this, bridge_t *bridge)
}
/**
- * disable the currently enabled template
+ * Implementation of dumm_t.add_overlay.
*/
-static void clear_template(private_dumm_t *this)
+static bool add_overlay(private_dumm_t *this, char *dir)
{
enumerator_t *enumerator;
guest_t *guest;
- free(this->template);
- this->template = NULL;
+ if (dir == NULL)
+ {
+ return TRUE;
+ }
+ if (strlen(dir) > PATH_MAX)
+ {
+ DBG1(DBG_LIB, "overlay directory string '%s' is too long", dir);
+ return FALSE;
+ }
+ if (access(dir, F_OK) != 0)
+ {
+ if (!mkdir_p(dir, PERME))
+ {
+ DBG1(DBG_LIB, "creating overlay directory '%s' failed: %m", dir);
+ return FALSE;
+ }
+ }
+ enumerator = this->guests->create_enumerator(this->guests);
+ while (enumerator->enumerate(enumerator, (void**)&guest))
+ {
+ char guest_dir[PATH_MAX];
+ int len = snprintf(guest_dir, sizeof(guest_dir), "%s/%s", dir,
+ guest->get_name(guest));
+ if (len < 0 || len >= sizeof(guest_dir))
+ {
+ goto error;
+ }
+ if (access(guest_dir, F_OK) != 0)
+ {
+ if (!mkdir_p(guest_dir, PERME))
+ {
+ DBG1(DBG_LIB, "creating overlay directory for guest '%s' failed: %m",
+ guest->get_name(guest));
+ goto error;
+ }
+ }
+ if (!guest->add_overlay(guest, guest_dir))
+ {
+ goto error;
+ }
+ }
+ enumerator->destroy(enumerator);
+ return TRUE;
+error:
+ enumerator->destroy(enumerator);
+ this->public.del_overlay(&this->public, dir);
+ return FALSE;
+}
+
+/**
+ * Implementation of dumm_t.del_overlay.
+ */
+static bool del_overlay(private_dumm_t *this, char *dir)
+{
+ bool ret = FALSE;
+ enumerator_t *enumerator;
+ guest_t *guest;
enumerator = this->guests->create_enumerator(this->guests);
while (enumerator->enumerate(enumerator, (void**)&guest))
{
- guest->load_template(guest, NULL);
+ char guest_dir[PATH_MAX];
+ int len = snprintf(guest_dir, sizeof(guest_dir), "%s/%s", dir,
+ guest->get_name(guest));
+ if (len < 0 || len >= sizeof(guest_dir))
+ {
+ continue;
+ }
+ ret = guest->del_overlay(guest, guest_dir) || ret;
}
enumerator->destroy(enumerator);
+ return ret;
}
/**
- * Implementation of dumm_t.load_template.
+ * Implementation of dumm_t.pop_overlay.
*/
-static bool load_template(private_dumm_t *this, char *dir)
+static bool pop_overlay(private_dumm_t *this)
{
+ bool ret = FALSE;
enumerator_t *enumerator;
guest_t *guest;
- clear_template(this);
+ enumerator = this->guests->create_enumerator(this->guests);
+ while (enumerator->enumerate(enumerator, (void**)&guest))
+ {
+ ret = guest->pop_overlay(guest) || ret;
+ }
+ enumerator->destroy(enumerator);
+ return ret;
+}
- if (dir == NULL)
+/**
+ * disable the currently enabled template
+ */
+static void clear_template(private_dumm_t *this)
+{
+ if (this->template)
+ {
+ del_overlay(this, this->template);
+ free(this->template);
+ this->template = NULL;
+ }
+}
+
+/**
+ * Implementation of dumm_t.load_template.
+ */
+static bool load_template(private_dumm_t *this, char *name)
+{
+ clear_template(this);
+ if (name == NULL)
{
return TRUE;
}
- if (strlen(dir) > PATH_MAX)
+ if (strlen(name) > PATH_MAX)
{
- DBG1(DBG_LIB, "template directory string '%s' is too long", dir);
+ DBG1(DBG_LIB, "template name '%s' is too long", name);
return FALSE;
}
-
- if (asprintf(&this->template, "%s/%s", TEMPLATE_DIR, dir) < 0)
+ if (strchr(name, '/') != NULL)
+ {
+ DBG1(DBG_LIB, "template name '%s' must not contain '/' characters", name);
+ return FALSE;
+ }
+ if (asprintf(&this->template, "%s/%s", TEMPLATE_DIR, name) < 0)
{
this->template = NULL;
return FALSE;
}
if (access(this->template, F_OK) != 0)
- { /* does not exist, create template */
+ {
if (!mkdir_p(this->template, PERME))
{
DBG1(DBG_LIB, "creating template directory '%s' failed: %m",
@@ -180,18 +274,7 @@ static bool load_template(private_dumm_t *this, char *dir)
return FALSE;
}
}
- enumerator = this->guests->create_enumerator(this->guests);
- while (enumerator->enumerate(enumerator, (void**)&guest))
- {
- if (!guest->load_template(guest, this->template))
- {
- enumerator->destroy(enumerator);
- clear_template(this);
- return FALSE;
- }
- }
- enumerator->destroy(enumerator);
- return TRUE;
+ return add_overlay(this, this->template);
}
/**
@@ -205,7 +288,7 @@ typedef struct {
} template_enumerator_t;
/**
- * Implementation of template_enumerator_t.enumerate
+ * Implementation of template_enumerator_t.enumerate.
*/
static bool template_enumerate(template_enumerator_t *this, char **template)
{
@@ -224,7 +307,7 @@ static bool template_enumerate(template_enumerator_t *this, char **template)
}
/**
- * Implementation of template_enumerator_t.destroy
+ * Implementation of template_enumerator_t.destroy.
*/
static void template_enumerator_destroy(template_enumerator_t *this)
{
@@ -233,22 +316,25 @@ static void template_enumerator_destroy(template_enumerator_t *this)
}
/**
- * Implementation of dumm_t.create_template_enumerator
+ * Implementation of dumm_t.create_template_enumerator.
*/
static enumerator_t* create_template_enumerator(private_dumm_t *this)
{
template_enumerator_t *enumerator;
-
enumerator = malloc_thing(template_enumerator_t);
enumerator->public.enumerate = (void*)template_enumerate;
enumerator->public.destroy = (void*)template_enumerator_destroy;
enumerator->inner = enumerator_create_directory(TEMPLATE_DIR);
-
+ if (!enumerator->inner)
+ {
+ free(enumerator);
+ return enumerator_create_empty();
+ }
return &enumerator->public;
}
/**
- * Implementation of dumm_t.destroy
+ * Implementation of dumm_t.destroy.
*/
static void destroy(private_dumm_t *this)
{
@@ -324,7 +410,10 @@ dumm_t *dumm_create(char *dir)
this->public.create_bridge = (bridge_t*(*)(dumm_t*, char *name))create_bridge;
this->public.create_bridge_enumerator = (enumerator_t*(*)(dumm_t*))create_bridge_enumerator;
this->public.delete_bridge = (void(*)(dumm_t*,bridge_t*))delete_bridge;
- this->public.load_template = (bool(*)(dumm_t*, char *name))load_template;
+ this->public.add_overlay = (bool(*)(dumm_t*,char*))add_overlay;
+ this->public.del_overlay = (bool(*)(dumm_t*,char*))del_overlay;
+ this->public.pop_overlay = (bool(*)(dumm_t*))pop_overlay;
+ this->public.load_template = (bool(*)(dumm_t*,char*))load_template;
this->public.create_template_enumerator = (enumerator_t*(*)(dumm_t*))create_template_enumerator;
this->public.destroy = (void(*)(dumm_t*))destroy;