Added support for multiple overlays to the main library.
Also implemented the template functionality using the new overlay functions.
This commit is contained in:
+135
-46
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2008 Tobias Brunner
|
* Copyright (C) 2008-2009 Tobias Brunner
|
||||||
* Copyright (C) 2007 Martin Willi
|
* Copyright (C) 2007 Martin Willi
|
||||||
* Hochschule fuer Technik Rapperswil
|
* 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;
|
enumerator_t *enumerator;
|
||||||
guest_t *guest;
|
guest_t *guest;
|
||||||
|
|
||||||
free(this->template);
|
|
||||||
this->template = NULL;
|
|
||||||
|
|
||||||
enumerator = this->guests->create_enumerator(this->guests);
|
|
||||||
while (enumerator->enumerate(enumerator, (void**)&guest))
|
|
||||||
{
|
|
||||||
guest->load_template(guest, NULL);
|
|
||||||
}
|
|
||||||
enumerator->destroy(enumerator);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Implementation of dumm_t.load_template.
|
|
||||||
*/
|
|
||||||
static bool load_template(private_dumm_t *this, char *dir)
|
|
||||||
{
|
|
||||||
enumerator_t *enumerator;
|
|
||||||
guest_t *guest;
|
|
||||||
|
|
||||||
clear_template(this);
|
|
||||||
|
|
||||||
if (dir == NULL)
|
if (dir == NULL)
|
||||||
{
|
{
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
if (strlen(dir) > PATH_MAX)
|
if (strlen(dir) > PATH_MAX)
|
||||||
{
|
{
|
||||||
DBG1(DBG_LIB, "template directory string '%s' is too long", dir);
|
DBG1(DBG_LIB, "overlay directory string '%s' is too long", dir);
|
||||||
return FALSE;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
if (asprintf(&this->template, "%s/%s", TEMPLATE_DIR, dir) < 0)
|
/**
|
||||||
|
* 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))
|
||||||
|
{
|
||||||
|
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.pop_overlay.
|
||||||
|
*/
|
||||||
|
static bool pop_overlay(private_dumm_t *this)
|
||||||
|
{
|
||||||
|
bool ret = FALSE;
|
||||||
|
enumerator_t *enumerator;
|
||||||
|
guest_t *guest;
|
||||||
|
|
||||||
|
enumerator = this->guests->create_enumerator(this->guests);
|
||||||
|
while (enumerator->enumerate(enumerator, (void**)&guest))
|
||||||
|
{
|
||||||
|
ret = guest->pop_overlay(guest) || ret;
|
||||||
|
}
|
||||||
|
enumerator->destroy(enumerator);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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(name) > PATH_MAX)
|
||||||
|
{
|
||||||
|
DBG1(DBG_LIB, "template name '%s' is too long", name);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
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;
|
this->template = NULL;
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
if (access(this->template, F_OK) != 0)
|
if (access(this->template, F_OK) != 0)
|
||||||
{ /* does not exist, create template */
|
{
|
||||||
if (!mkdir_p(this->template, PERME))
|
if (!mkdir_p(this->template, PERME))
|
||||||
{
|
{
|
||||||
DBG1(DBG_LIB, "creating template directory '%s' failed: %m",
|
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;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
enumerator = this->guests->create_enumerator(this->guests);
|
return add_overlay(this, this->template);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -205,7 +288,7 @@ typedef struct {
|
|||||||
} template_enumerator_t;
|
} 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)
|
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)
|
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)
|
static enumerator_t* create_template_enumerator(private_dumm_t *this)
|
||||||
{
|
{
|
||||||
template_enumerator_t *enumerator;
|
template_enumerator_t *enumerator;
|
||||||
|
|
||||||
enumerator = malloc_thing(template_enumerator_t);
|
enumerator = malloc_thing(template_enumerator_t);
|
||||||
enumerator->public.enumerate = (void*)template_enumerate;
|
enumerator->public.enumerate = (void*)template_enumerate;
|
||||||
enumerator->public.destroy = (void*)template_enumerator_destroy;
|
enumerator->public.destroy = (void*)template_enumerator_destroy;
|
||||||
enumerator->inner = enumerator_create_directory(TEMPLATE_DIR);
|
enumerator->inner = enumerator_create_directory(TEMPLATE_DIR);
|
||||||
|
if (!enumerator->inner)
|
||||||
|
{
|
||||||
|
free(enumerator);
|
||||||
|
return enumerator_create_empty();
|
||||||
|
}
|
||||||
return &enumerator->public;
|
return &enumerator->public;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implementation of dumm_t.destroy
|
* Implementation of dumm_t.destroy.
|
||||||
*/
|
*/
|
||||||
static void destroy(private_dumm_t *this)
|
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 = (bridge_t*(*)(dumm_t*, char *name))create_bridge;
|
||||||
this->public.create_bridge_enumerator = (enumerator_t*(*)(dumm_t*))create_bridge_enumerator;
|
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.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.create_template_enumerator = (enumerator_t*(*)(dumm_t*))create_template_enumerator;
|
||||||
this->public.destroy = (void(*)(dumm_t*))destroy;
|
this->public.destroy = (void(*)(dumm_t*))destroy;
|
||||||
|
|
||||||
|
|||||||
+38
-3
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (C) 2008 Tobias Brunner
|
* Copyright (C) 2008-2009 Tobias Brunner
|
||||||
* Copyright (C) 2007 Martin Willi
|
* Copyright (C) 2007 Martin Willi
|
||||||
* Hochschule fuer Technik Rapperswil
|
* Hochschule fuer Technik Rapperswil
|
||||||
*
|
*
|
||||||
@@ -82,13 +82,48 @@ struct dumm_t {
|
|||||||
*/
|
*/
|
||||||
void (*delete_bridge) (dumm_t *this, bridge_t *bridge);
|
void (*delete_bridge) (dumm_t *this, bridge_t *bridge);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add an overlay to all guests.
|
||||||
|
*
|
||||||
|
* Directories named after the guests are created, if they do not exist
|
||||||
|
* in the given overlay directory.
|
||||||
|
*
|
||||||
|
* If adding the overlay on at lest one guest fails, FALSE is returned and
|
||||||
|
* the overlay is again removed from all guests.
|
||||||
|
*
|
||||||
|
* @param dir dir to the overlay
|
||||||
|
* @return FALSE, on failure
|
||||||
|
*/
|
||||||
|
bool (*add_overlay)(dumm_t *this, char *dir);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes an overlay from all guests.
|
||||||
|
*
|
||||||
|
* @param dir dir to the overlay
|
||||||
|
* @return FALSE, if the overlay was not found on any guest
|
||||||
|
*/
|
||||||
|
bool (*del_overlay)(dumm_t *this, char *dir);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Remove the latest overlay from all guests.
|
||||||
|
*
|
||||||
|
* @return FALSE, if no overlay was found on any guest
|
||||||
|
*/
|
||||||
|
bool (*pop_overlay)(dumm_t *this);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads a template, create a new one if it does not exist.
|
* Loads a template, create a new one if it does not exist.
|
||||||
*
|
*
|
||||||
* @param name dir to the template, NULL to close
|
* This is basically a wrapper around add/del_overlay to simplify working
|
||||||
|
* with overlays. Templates are located in a predefined directory, so that
|
||||||
|
* only a name for the template has to be specified here. Only one template
|
||||||
|
* can be loaded at any one time (but other overlays can be added on top or
|
||||||
|
* below a template).
|
||||||
|
*
|
||||||
|
* @param name name of the template to load, NULL to unload
|
||||||
* @return FALSE if load/create failed
|
* @return FALSE if load/create failed
|
||||||
*/
|
*/
|
||||||
bool (*load_template)(dumm_t *this, char *dir);
|
bool (*load_template)(dumm_t *this, char *name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an enumerator over all available templates.
|
* Create an enumerator over all available templates.
|
||||||
|
|||||||
Reference in New Issue
Block a user