diff options
Diffstat (limited to 'src/dumm/dumm.c')
-rw-r--r-- | src/dumm/dumm.c | 444 |
1 files changed, 0 insertions, 444 deletions
diff --git a/src/dumm/dumm.c b/src/dumm/dumm.c deleted file mode 100644 index e24671330..000000000 --- a/src/dumm/dumm.c +++ /dev/null @@ -1,444 +0,0 @@ -/* - * Copyright (C) 2008-2009 Tobias Brunner - * Copyright (C) 2007 Martin Willi - * HSR Hochschule fuer Technik Rapperswil - * - * This program is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License as published by the - * Free Software Foundation; either version 2 of the License, or (at your - * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>. - * - * This program 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 General Public License - * for more details. - */ - -#define _GNU_SOURCE - -#include <sys/types.h> -#include <sys/stat.h> -#include <unistd.h> -#include <stdio.h> -#include <dirent.h> -#include <errno.h> - -#include <utils/debug.h> -#include <collections/linked_list.h> - -#include "dumm.h" - -#define PERME (S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH) -#define GUEST_DIR "guests" -#define TEMPLATE_DIR "templates" - -typedef struct private_dumm_t private_dumm_t; - -struct private_dumm_t { - /** public dumm interface */ - dumm_t public; - /** working dir */ - char *dir; - /** directory of guests */ - char *guest_dir; - /** directory of loaded template */ - char *template; - /** list of managed guests */ - linked_list_t *guests; - /** list of managed bridges */ - linked_list_t *bridges; -}; - -METHOD(dumm_t, create_guest, guest_t*, - private_dumm_t *this, char *name, char *kernel, char *master, char *args) -{ - guest_t *guest; - - guest = guest_create(this->guest_dir, name, kernel, master, args); - if (guest) - { - this->guests->insert_last(this->guests, guest); - } - return guest; -} - -METHOD(dumm_t, create_guest_enumerator, enumerator_t*, - private_dumm_t *this) -{ - return this->guests->create_enumerator(this->guests); -} - -METHOD(dumm_t, delete_guest, void, - private_dumm_t *this, guest_t *guest) -{ - if (this->guests->remove(this->guests, guest, NULL)) - { - char buf[512]; - int len; - - len = snprintf(buf, sizeof(buf), "rm -Rf %s/%s", - this->guest_dir, guest->get_name(guest)); - guest->destroy(guest); - if (len > 8 && len < 512) - { - ignore_result(system(buf)); - } - } -} - -METHOD(dumm_t, create_bridge, bridge_t*, - private_dumm_t *this, char *name) -{ - bridge_t *bridge; - - bridge = bridge_create(name); - if (bridge) - { - this->bridges->insert_last(this->bridges, bridge); - } - return bridge; -} - -METHOD(dumm_t, create_bridge_enumerator, enumerator_t*, - private_dumm_t *this) -{ - return this->bridges->create_enumerator(this->bridges); -} - -METHOD(dumm_t, delete_bridge, void, - private_dumm_t *this, bridge_t *bridge) -{ - if (this->bridges->remove(this->bridges, bridge, NULL)) - { - bridge->destroy(bridge); - } -} - -METHOD(dumm_t, add_overlay, bool, - private_dumm_t *this, char *dir) -{ - enumerator_t *enumerator; - guest_t *guest; - - 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; -} - -METHOD(dumm_t, del_overlay, bool, - 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; -} - -METHOD(dumm_t, pop_overlay, bool, - 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; - } -} - -METHOD(dumm_t, load_template, bool, - 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; - return FALSE; - } - if (access(this->template, F_OK) != 0) - { - if (!mkdir_p(this->template, PERME)) - { - DBG1(DBG_LIB, "creating template directory '%s' failed: %m", - this->template); - return FALSE; - } - } - return add_overlay(this, this->template); -} - -/** - * Template directory enumerator - */ -typedef struct { - /** implements enumerator_t */ - enumerator_t public; - /** directory enumerator */ - enumerator_t *inner; -} template_enumerator_t; - -METHOD(enumerator_t, template_enumerate, bool, - template_enumerator_t *this, va_list args) -{ - struct stat st; - char *rel, **template; - - VA_ARGS_VGET(args, template); - - while (this->inner->enumerate(this->inner, &rel, NULL, &st)) - { - if (S_ISDIR(st.st_mode) && *rel != '.') - { - *template = rel; - return TRUE; - } - } - return FALSE; -} - -METHOD(enumerator_t, template_enumerator_destroy, void, - template_enumerator_t *this) -{ - this->inner->destroy(this->inner); - free(this); -} - -METHOD(dumm_t, create_template_enumerator, enumerator_t*, - private_dumm_t *this) -{ - template_enumerator_t *enumerator; - INIT(enumerator, - .public = { - .enumerate = enumerator_enumerate_default, - .venumerate = _template_enumerate, - .destroy = (void*)_template_enumerator_destroy, - }, - .inner = enumerator_create_directory(TEMPLATE_DIR), - ); - if (!enumerator->inner) - { - free(enumerator); - return enumerator_create_empty(); - } - return &enumerator->public; -} - -METHOD(dumm_t, destroy, void, - private_dumm_t *this) -{ - enumerator_t *enumerator; - guest_t *guest; - - this->bridges->destroy_offset(this->bridges, offsetof(bridge_t, destroy)); - - enumerator = this->guests->create_enumerator(this->guests); - while (enumerator->enumerate(enumerator, (void**)&guest)) - { - guest->stop(guest, NULL); - } - enumerator->destroy(enumerator); - - while (this->guests->remove_last(this->guests, (void**)&guest) == SUCCESS) - { - guest->destroy(guest); - } - this->guests->destroy(this->guests); - free(this->guest_dir); - free(this->template); - free(this->dir); - free(this); -} - -/** - * load all guests in our working dir - */ -static void load_guests(private_dumm_t *this) -{ - DIR *dir; - struct dirent *ent; - guest_t *guest; - - dir = opendir(this->guest_dir); - if (dir == NULL) - { - return; - } - - while ((ent = readdir(dir))) - { - if (*ent->d_name == '.') - { /* skip ".", ".." and hidden files (such as ".svn") */ - continue; - } - guest = guest_load(this->guest_dir, ent->d_name); - if (guest) - { - this->guests->insert_last(this->guests, guest); - } - else - { - DBG1(DBG_LIB, "loading guest in directory '%s' failed, skipped", - ent->d_name); - } - } - closedir(dir); -} - -/** - * create a dumm instance - */ -dumm_t *dumm_create(char *dir) -{ - char cwd[PATH_MAX]; - private_dumm_t *this; - - INIT(this, - .public = { - .create_guest = _create_guest, - .create_guest_enumerator = _create_guest_enumerator, - .delete_guest = _delete_guest, - .create_bridge = _create_bridge, - .create_bridge_enumerator = _create_bridge_enumerator, - .delete_bridge = _delete_bridge, - .add_overlay = _add_overlay, - .del_overlay = _del_overlay, - .pop_overlay = _pop_overlay, - .load_template = _load_template, - .create_template_enumerator = _create_template_enumerator, - .destroy = _destroy, - }, - ); - - if (dir && *dir == '/') - { - this->dir = strdup(dir); - } - else - { - if (getcwd(cwd, sizeof(cwd)) == NULL) - { - free(this); - return NULL; - } - if (dir) - { - if (asprintf(&this->dir, "%s/%s", cwd, dir) < 0) - { - this->dir = NULL; - } - } - else - { - this->dir = strdup(cwd); - } - } - if (asprintf(&this->guest_dir, "%s/%s", this->dir, GUEST_DIR) < 0) - { - this->guest_dir = NULL; - } - - this->guests = linked_list_create(); - this->bridges = linked_list_create(); - - if (this->dir == NULL || this->guest_dir == NULL || - (mkdir(this->guest_dir, PERME) < 0 && errno != EEXIST)) - { - DBG1(DBG_LIB, "creating guest directory '%s' failed: %m", - this->guest_dir); - destroy(this); - return NULL; - } - - load_guests(this); - return &this->public; -} - |