share some code between IMC and IMV managers
This commit is contained in:
@@ -18,15 +18,7 @@
|
||||
|
||||
#include <tncifimc.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <utils/linked_list.h>
|
||||
#include <utils/lexparser.h>
|
||||
#include <debug.h>
|
||||
|
||||
typedef struct private_tnc_imc_manager_t private_tnc_imc_manager_t;
|
||||
@@ -101,121 +93,30 @@ METHOD(imc_manager_t, remove_, imc_t*,
|
||||
return removed_imc;
|
||||
}
|
||||
|
||||
METHOD(imc_manager_t, load_all, bool,
|
||||
private_tnc_imc_manager_t *this, char *filename)
|
||||
METHOD(imc_manager_t, load, bool,
|
||||
private_tnc_imc_manager_t *this, char *name, char *path)
|
||||
{
|
||||
int fd, line_nr = 0;
|
||||
chunk_t src, line;
|
||||
struct stat sb;
|
||||
void *addr;
|
||||
imc_t *imc;
|
||||
|
||||
DBG1(DBG_TNC, "loading IMCs from '%s'", filename);
|
||||
fd = open(filename, O_RDONLY);
|
||||
if (fd == -1)
|
||||
imc = tnc_imc_create(name, path);
|
||||
if (!imc)
|
||||
{
|
||||
DBG1(DBG_TNC, "opening configuration file '%s' failed: %s", filename,
|
||||
strerror(errno));
|
||||
free(name);
|
||||
free(path);
|
||||
return FALSE;
|
||||
}
|
||||
if (fstat(fd, &sb) == -1)
|
||||
if (!add(this, imc))
|
||||
{
|
||||
DBG1(DBG_LIB, "getting file size of '%s' failed: %s", filename,
|
||||
strerror(errno));
|
||||
close(fd);
|
||||
if (imc->terminate &&
|
||||
imc->terminate(imc->get_id(imc)) != TNC_RESULT_SUCCESS)
|
||||
{
|
||||
DBG1(DBG_TNC, "IMC \"%s\" not terminated successfully",
|
||||
imc->get_name(imc));
|
||||
}
|
||||
imc->destroy(imc);
|
||||
return FALSE;
|
||||
}
|
||||
addr = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
|
||||
if (addr == MAP_FAILED)
|
||||
{
|
||||
DBG1(DBG_LIB, "mapping '%s' failed: %s", filename, strerror(errno));
|
||||
close(fd);
|
||||
return FALSE;
|
||||
}
|
||||
src = chunk_create(addr, sb.st_size);
|
||||
|
||||
while (fetchline(&src, &line))
|
||||
{
|
||||
char *name, *path;
|
||||
chunk_t token;
|
||||
imc_t *imc;
|
||||
|
||||
line_nr++;
|
||||
|
||||
/* skip comments or empty lines */
|
||||
if (*line.ptr == '#' || !eat_whitespace(&line))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* determine keyword */
|
||||
if (!extract_token(&token, ' ', &line))
|
||||
{
|
||||
DBG1(DBG_TNC, "line %d: keyword must be followed by a space",
|
||||
line_nr);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* only interested in IMCs */
|
||||
if (!match("IMC", &token))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* advance to the IMC name and extract it */
|
||||
if (!extract_token(&token, '"', &line) ||
|
||||
!extract_token(&token, '"', &line))
|
||||
{
|
||||
DBG1(DBG_TNC, "line %d: IMC name must be set in double quotes",
|
||||
line_nr);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* copy the IMC name */
|
||||
name = malloc(token.len + 1);
|
||||
memcpy(name, token.ptr, token.len);
|
||||
name[token.len] = '\0';
|
||||
|
||||
/* advance to the IMC path and extract it */
|
||||
if (!eat_whitespace(&line))
|
||||
{
|
||||
DBG1(DBG_TNC, "line %d: IMC path is missing", line_nr);
|
||||
free(name);
|
||||
return FALSE;
|
||||
}
|
||||
if (!extract_token(&token, ' ', &line))
|
||||
{
|
||||
token = line;
|
||||
}
|
||||
|
||||
/* copy the IMC path */
|
||||
path = malloc(token.len + 1);
|
||||
memcpy(path, token.ptr, token.len);
|
||||
path[token.len] = '\0';
|
||||
|
||||
/* load and register IMC instance */
|
||||
imc = tnc_imc_create(name, path);
|
||||
if (!imc)
|
||||
{
|
||||
free(name);
|
||||
free(path);
|
||||
return FALSE;
|
||||
}
|
||||
if (!add(this, imc))
|
||||
{
|
||||
if (imc->terminate &&
|
||||
imc->terminate(imc->get_id(imc)) != TNC_RESULT_SUCCESS)
|
||||
{
|
||||
DBG1(DBG_TNC, "IMC \"%s\" not terminated successfully",
|
||||
imc->get_name(imc));
|
||||
}
|
||||
imc->destroy(imc);
|
||||
return FALSE;
|
||||
}
|
||||
DBG1(DBG_TNC, "IMC %u \"%s\" loaded from '%s'", imc->get_id(imc),
|
||||
name, path);
|
||||
}
|
||||
munmap(addr, sb.st_size);
|
||||
close(fd);
|
||||
DBG1(DBG_TNC, "IMC %u \"%s\" loaded from '%s'", imc->get_id(imc), name, path);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -376,7 +277,7 @@ imc_manager_t* tnc_imc_manager_create(void)
|
||||
.public = {
|
||||
.add = _add,
|
||||
.remove = _remove_, /* avoid name conflict with stdio.h */
|
||||
.load_all = _load_all,
|
||||
.load = _load,
|
||||
.is_registered = _is_registered,
|
||||
.get_preferred_language = _get_preferred_language,
|
||||
.notify_connection_change = _notify_connection_change,
|
||||
|
||||
@@ -110,121 +110,30 @@ METHOD(imv_manager_t, remove_, imv_t*,
|
||||
return removed_imv;
|
||||
}
|
||||
|
||||
METHOD(imv_manager_t, load_all, bool,
|
||||
private_tnc_imv_manager_t *this, char *filename)
|
||||
METHOD(imv_manager_t, load, bool,
|
||||
private_tnc_imv_manager_t *this, char *name, char *path)
|
||||
{
|
||||
int fd, line_nr = 0;
|
||||
chunk_t src, line;
|
||||
struct stat sb;
|
||||
void *addr;
|
||||
imv_t *imv;
|
||||
|
||||
DBG1(DBG_TNC, "loading IMVs from '%s'", filename);
|
||||
fd = open(filename, O_RDONLY);
|
||||
if (fd == -1)
|
||||
imv = tnc_imv_create(name, path);
|
||||
if (!imv)
|
||||
{
|
||||
DBG1(DBG_TNC, "opening configuration file '%s' failed: %s", filename,
|
||||
strerror(errno));
|
||||
free(name);
|
||||
free(path);
|
||||
return FALSE;
|
||||
}
|
||||
if (fstat(fd, &sb) == -1)
|
||||
if (!add(this, imv))
|
||||
{
|
||||
DBG1(DBG_LIB, "getting file size of '%s' failed: %s", filename,
|
||||
strerror(errno));
|
||||
close(fd);
|
||||
if (imv->terminate &&
|
||||
imv->terminate(imv->get_id(imv)) != TNC_RESULT_SUCCESS)
|
||||
{
|
||||
DBG1(DBG_TNC, "IMV \"%s\" not terminated successfully",
|
||||
imv->get_name(imv));
|
||||
}
|
||||
imv->destroy(imv);
|
||||
return FALSE;
|
||||
}
|
||||
addr = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
|
||||
if (addr == MAP_FAILED)
|
||||
{
|
||||
DBG1(DBG_LIB, "mapping '%s' failed: %s", filename, strerror(errno));
|
||||
close(fd);
|
||||
return FALSE;
|
||||
}
|
||||
src = chunk_create(addr, sb.st_size);
|
||||
|
||||
while (fetchline(&src, &line))
|
||||
{
|
||||
char *name, *path;
|
||||
chunk_t token;
|
||||
imv_t *imv;
|
||||
|
||||
line_nr++;
|
||||
|
||||
/* skip comments or empty lines */
|
||||
if (*line.ptr == '#' || !eat_whitespace(&line))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* determine keyword */
|
||||
if (!extract_token(&token, ' ', &line))
|
||||
{
|
||||
DBG1(DBG_TNC, "line %d: keyword must be followed by a space",
|
||||
line_nr);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* only interested in IMVs */
|
||||
if (!match("IMV", &token))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* advance to the IMV name and extract it */
|
||||
if (!extract_token(&token, '"', &line) ||
|
||||
!extract_token(&token, '"', &line))
|
||||
{
|
||||
DBG1(DBG_TNC, "line %d: IMV name must be set in double quotes",
|
||||
line_nr);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* copy the IMV name */
|
||||
name = malloc(token.len + 1);
|
||||
memcpy(name, token.ptr, token.len);
|
||||
name[token.len] = '\0';
|
||||
|
||||
/* advance to the IMV path and extract it */
|
||||
if (!eat_whitespace(&line))
|
||||
{
|
||||
DBG1(DBG_TNC, "line %d: IMV path is missing", line_nr);
|
||||
free(name);
|
||||
return FALSE;
|
||||
}
|
||||
if (!extract_token(&token, ' ', &line))
|
||||
{
|
||||
token = line;
|
||||
}
|
||||
|
||||
/* copy the IMV path */
|
||||
path = malloc(token.len + 1);
|
||||
memcpy(path, token.ptr, token.len);
|
||||
path[token.len] = '\0';
|
||||
|
||||
/* load and register IMV instance */
|
||||
imv = tnc_imv_create(name, path);
|
||||
if (!imv)
|
||||
{
|
||||
free(name);
|
||||
free(path);
|
||||
return FALSE;
|
||||
}
|
||||
if (!add(this, imv))
|
||||
{
|
||||
if (imv->terminate &&
|
||||
imv->terminate(imv->get_id(imv)) != TNC_RESULT_SUCCESS)
|
||||
{
|
||||
DBG1(DBG_TNC, "IMV \"%s\" not terminated successfully",
|
||||
imv->get_name(imv));
|
||||
}
|
||||
imv->destroy(imv);
|
||||
return FALSE;
|
||||
}
|
||||
DBG1(DBG_TNC, "IMV %u \"%s\" loaded from '%s'", imv->get_id(imv),
|
||||
name, path);
|
||||
}
|
||||
munmap(addr, sb.st_size);
|
||||
close(fd);
|
||||
DBG1(DBG_TNC, "IMV %u \"%s\" loaded from '%s'", imv->get_id(imv), name, path);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -448,7 +357,7 @@ imv_manager_t* tnc_imv_manager_create(void)
|
||||
.public = {
|
||||
.add = _add,
|
||||
.remove = _remove_, /* avoid name conflict with stdio.h */
|
||||
.load_all = _load_all,
|
||||
.load = _load,
|
||||
.is_registered = _is_registered,
|
||||
.get_recommendation_policy = _get_recommendation_policy,
|
||||
.create_recommendations = _create_recommendations,
|
||||
|
||||
@@ -49,12 +49,13 @@ struct imc_manager_t {
|
||||
imc_t* (*remove)(imc_manager_t *this, TNC_IMCID id);
|
||||
|
||||
/**
|
||||
* Load all IMC instances
|
||||
* Load and initialize an IMC as a dynamic library and add it to the list
|
||||
*
|
||||
* @param filename configuration file containt IMC paths
|
||||
* @return TRUE if initialization of all IMCs succeeded
|
||||
* @param name name of the IMC to be loaded
|
||||
* @param path path of the IMC dynamic library file
|
||||
* @return TRUE if loading succeeded
|
||||
*/
|
||||
bool (*load_all)(imc_manager_t *this, char *filename);
|
||||
bool (*load)(imc_manager_t *this, char *name, char *path);
|
||||
|
||||
/**
|
||||
* Check if an IMC with a given ID is registered with the IMC manager
|
||||
|
||||
@@ -50,12 +50,14 @@ struct imv_manager_t {
|
||||
imv_t* (*remove)(imv_manager_t *this, TNC_IMVID id);
|
||||
|
||||
/**
|
||||
* Load all IMV instances
|
||||
* Load and initialize an IMV as a dynamic library and add it to the list
|
||||
*
|
||||
* @param filename configuration file containing IMV paths
|
||||
* @return TRUE if initialization of all IMVs succeeded
|
||||
* @param name name of the IMV to be loaded
|
||||
* @param path path of the IMV dynamic library file
|
||||
* @return TRUE if loading succeeded
|
||||
*/
|
||||
bool (*load_all)(imv_manager_t *this, char *filename);
|
||||
bool (*load)(imv_manager_t *this, char *name, char *path);
|
||||
|
||||
|
||||
/**
|
||||
* Check if an IMV with a given ID is registered with the IMV manager
|
||||
|
||||
+150
-19
@@ -15,6 +15,16 @@
|
||||
|
||||
#include "tnc.h"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#include <utils/lexparser.h>
|
||||
#include <debug.h>
|
||||
|
||||
typedef struct private_tnc_t private_tnc_t;
|
||||
|
||||
typedef tnccs_manager_t *(*tnc_create_tnccs_manager_t)(void);
|
||||
@@ -63,16 +73,126 @@ void libtnccs_deinit(void)
|
||||
tnc = NULL;
|
||||
}
|
||||
|
||||
static bool load_imcvs_from_config(char *filename, bool is_imc)
|
||||
{
|
||||
int fd, line_nr = 0;
|
||||
chunk_t src, line;
|
||||
struct stat sb;
|
||||
void *addr;
|
||||
char *label;
|
||||
|
||||
label = is_imc ? "IMC" : "IMV";
|
||||
|
||||
DBG1(DBG_TNC, "loading %ss from '%s'", label, filename);
|
||||
fd = open(filename, O_RDONLY);
|
||||
if (fd == -1)
|
||||
{
|
||||
DBG1(DBG_TNC, "opening configuration file '%s' failed: %s", filename,
|
||||
strerror(errno));
|
||||
return FALSE;
|
||||
}
|
||||
if (fstat(fd, &sb) == -1)
|
||||
{
|
||||
DBG1(DBG_LIB, "getting file size of '%s' failed: %s", filename,
|
||||
strerror(errno));
|
||||
close(fd);
|
||||
return FALSE;
|
||||
}
|
||||
addr = mmap(NULL, sb.st_size, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
|
||||
if (addr == MAP_FAILED)
|
||||
{
|
||||
DBG1(DBG_LIB, "mapping '%s' failed: %s", filename, strerror(errno));
|
||||
close(fd);
|
||||
return FALSE;
|
||||
}
|
||||
src = chunk_create(addr, sb.st_size);
|
||||
|
||||
while (fetchline(&src, &line))
|
||||
{
|
||||
char *name, *path;
|
||||
bool success;
|
||||
chunk_t token;
|
||||
|
||||
line_nr++;
|
||||
|
||||
/* skip comments or empty lines */
|
||||
if (*line.ptr == '#' || !eat_whitespace(&line))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* determine keyword */
|
||||
if (!extract_token(&token, ' ', &line))
|
||||
{
|
||||
DBG1(DBG_TNC, "line %d: keyword must be followed by a space",
|
||||
line_nr);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* only interested in IMCs or IMVs depending on label */
|
||||
if (!match(label, &token))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
/* advance to the IMC/IMV name and extract it */
|
||||
if (!extract_token(&token, '"', &line) ||
|
||||
!extract_token(&token, '"', &line))
|
||||
{
|
||||
DBG1(DBG_TNC, "line %d: %s name must be set in double quotes",
|
||||
line_nr, label);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* copy the IMC/IMV name */
|
||||
name = malloc(token.len + 1);
|
||||
memcpy(name, token.ptr, token.len);
|
||||
name[token.len] = '\0';
|
||||
|
||||
/* advance to the IMC/IMV path and extract it */
|
||||
if (!eat_whitespace(&line))
|
||||
{
|
||||
DBG1(DBG_TNC, "line %d: %s path is missing", line_nr, label);
|
||||
free(name);
|
||||
return FALSE;
|
||||
}
|
||||
if (!extract_token(&token, ' ', &line))
|
||||
{
|
||||
token = line;
|
||||
}
|
||||
|
||||
/* copy the IMC/IMV path */
|
||||
path = malloc(token.len + 1);
|
||||
memcpy(path, token.ptr, token.len);
|
||||
path[token.len] = '\0';
|
||||
|
||||
/* load and register an IMC/IMV instance */
|
||||
if (is_imc)
|
||||
{
|
||||
success = tnc->imcs->load(tnc->imcs, name, path);
|
||||
}
|
||||
else
|
||||
{
|
||||
success = tnc->imvs->load(tnc->imvs, name, path);
|
||||
}
|
||||
if (!success)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
munmap(addr, sb.st_size);
|
||||
close(fd);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Described in header.
|
||||
*/
|
||||
bool tnc_manager_register(plugin_t *plugin, plugin_feature_t *feature,
|
||||
bool reg, void *data)
|
||||
{
|
||||
char *tnc_config;
|
||||
|
||||
tnc_config = lib->settings->get_str(lib->settings,
|
||||
"libtnccs.tnc_config", "/etc/tnc_config");
|
||||
bool load_imcvs = FALSE;
|
||||
bool is_imc = FALSE;
|
||||
|
||||
if (feature->type == FEATURE_CUSTOM)
|
||||
{
|
||||
@@ -93,14 +213,8 @@ bool tnc_manager_register(plugin_t *plugin, plugin_feature_t *feature,
|
||||
if (reg)
|
||||
{
|
||||
tnc->imcs = ((tnc_create_imc_manager_t)data)();
|
||||
|
||||
|
||||
if (!tnc->imcs->load_all(tnc->imcs, tnc_config))
|
||||
{
|
||||
tnc->imcs->destroy(tnc->imcs);
|
||||
tnc->imcs = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
is_imc = TRUE;
|
||||
load_imcvs = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -113,13 +227,8 @@ bool tnc_manager_register(plugin_t *plugin, plugin_feature_t *feature,
|
||||
if (reg)
|
||||
{
|
||||
tnc->imvs = ((tnc_create_imv_manager_t)data)();
|
||||
|
||||
if (!tnc->imvs->load_all(tnc->imvs, tnc_config))
|
||||
{
|
||||
tnc->imvs->destroy(tnc->imvs);
|
||||
tnc->imvs = NULL;
|
||||
return FALSE;
|
||||
}
|
||||
is_imc = FALSE;
|
||||
load_imcvs = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -131,6 +240,28 @@ bool tnc_manager_register(plugin_t *plugin, plugin_feature_t *feature,
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (load_imcvs)
|
||||
{
|
||||
char *tnc_config;
|
||||
|
||||
tnc_config = lib->settings->get_str(lib->settings,
|
||||
"libtnccs.tnc_config", "/etc/tnc_config");
|
||||
if (!load_imcvs_from_config(tnc_config, is_imc))
|
||||
{
|
||||
if (is_imc)
|
||||
{
|
||||
tnc->imcs->destroy(tnc->imcs);
|
||||
tnc->imcs = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
tnc->imvs->destroy(tnc->imvs);
|
||||
tnc->imvs = NULL;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user