Skip to content
Snippets Groups Projects
Commit 49bfee6b authored by Daniel Salzman's avatar Daniel Salzman
Browse files

Merge branch 'config-includes-fclose' of /git/repositories/labs/knot

parents a914adc9 9c18e094
No related branches found
No related tags found
No related merge requests found
......@@ -299,11 +299,16 @@ hmac-sha512 { lval.alg = KNOT_TSIG_ALG_HMAC_SHA512; return TSIG_ALGO_NAME; }
: /* Optional : in assignments. */;
<<EOF>> {
char *name = conf_includes_pop(yyextra->includes);
free(name);
conf_include_t *inc = conf_includes_pop(yyextra->includes);
free(inc->filename);
if (inc->handle) {
fclose(inc->handle);
}
yypop_buffer_state(yyscanner);
if (!YY_CURRENT_BUFFER)
if (!YY_CURRENT_BUFFER) {
return END;
}
}
<include>{BLANK}+
......@@ -326,16 +331,17 @@ hmac-sha512 { lval.alg = KNOT_TSIG_ALG_HMAC_SHA512; return TSIG_ALGO_NAME; }
}
// retrieved relative to previous config
char *filename = conf_includes_top(yyextra->includes);
conf_include_t *inc = conf_includes_top(yyextra->includes);
FILE *included = fopen(filename, "r");
FILE *included = fopen(inc->filename, "r");
if (!included) {
cf_error(yyscanner, "cannot open file '%s'", filename);
cf_error(yyscanner, "cannot open file '%s'", inc->filename);
conf_includes_pop(yyextra->includes);
free(filename);
free(inc->filename);
return END;
}
inc->handle = included;
YY_BUFFER_STATE bs = yy_create_buffer(included, YY_BUF_SIZE, yyscanner);
yypush_buffer_state(bs, yyscanner);
}
......
......@@ -70,17 +70,22 @@ static void cf_print_error(void *scanner, const char *msg)
int lineno = -1;
char *text = "?";
char *filename = NULL;
conf_include_t *inc = NULL;
if (scanner) {
extra = cf_get_extra(scanner);
lineno = cf_get_lineno(scanner);
text = cf_get_text(scanner);
filename = conf_includes_top(extra->includes);
inc = conf_includes_top(extra->includes);
extra->error = true;
}
if (!filename)
if (inc && inc->filename) {
filename = inc->filename;
} else {
filename = new_config->filename;
}
log_server_error("Config error in '%s' (line %d token '%s') - %s\n",
filename, lineno, text, msg);
......
......@@ -27,9 +27,9 @@
* \brief Structure to store names of files included into the config.
*/
struct conf_includes {
int free_index; //!< First free index in 'names'.
int capacity; //!< Maximal capacity.
char *names[0]; //!< Pointers to store file names.
int free_index; //!< First free index in 'names'.
int capacity; //!< Maximal capacity.
conf_include_t files[0]; //!< Stored includes.
};
/*!
......@@ -37,13 +37,16 @@ struct conf_includes {
*/
conf_includes_t *conf_includes_init(int capacity)
{
if (capacity <= 0)
if (capacity <= 0) {
return NULL;
}
size_t size = sizeof(conf_includes_t) + (capacity * sizeof(char *));
size_t size = sizeof(conf_includes_t)
+ (capacity * sizeof(conf_include_t *));
conf_includes_t *result = calloc(1, size);
if (!result)
if (!result) {
return NULL;
}
result->capacity = capacity;
return result;
......@@ -54,11 +57,13 @@ conf_includes_t *conf_includes_init(int capacity)
*/
void conf_includes_free(conf_includes_t *includes)
{
if (!includes)
if (!includes) {
return;
}
for (int i = 0; i < includes->free_index; i++)
free(includes->names[i]);
for (int i = 0; i < includes->free_index; i++) {
free(includes->files[i].filename);
}
free(includes);
}
......@@ -68,8 +73,9 @@ void conf_includes_free(conf_includes_t *includes)
*/
bool conf_includes_can_push(conf_includes_t *includes)
{
if (!includes)
if (!includes) {
return false;
}
return includes->free_index < includes->capacity;
}
......@@ -87,14 +93,16 @@ bool conf_includes_can_push(conf_includes_t *includes)
static char *path_relative_to(const char *filename, const char *reference)
{
char *path_end = strrchr(reference, '/');
if (!path_end)
if (!path_end) {
return strdup(filename);
}
int path_len = (int)(path_end - reference);
size_t result_len = path_len + 1 + strlen(filename) + 1;
char *result = malloc(result_len * sizeof(char));
if (!result)
if (!result) {
return NULL;
}
int w;
w = snprintf(result, result_len, "%.*s/%s", path_len, reference, filename);
......@@ -108,44 +116,54 @@ static char *path_relative_to(const char *filename, const char *reference)
*/
bool conf_includes_push(conf_includes_t *includes, const char *filename)
{
if (!includes || !filename)
if (!includes || !filename) {
return false;
}
if (!conf_includes_can_push(includes))
if (!conf_includes_can_push(includes)) {
return false;
}
char *store = NULL;
if (includes->free_index == 0 || filename[0] == '/') {
store = strdup(filename);
} else {
char *previous = includes->names[includes->free_index - 1];
store = path_relative_to(filename, previous);
conf_include_t *previous = &includes->files[includes->free_index - 1];
store = path_relative_to(filename, previous->filename);
}
includes->names[includes->free_index++] = store;
conf_include_t new_include = {
.filename = store,
.handle = NULL
};
includes->files[includes->free_index++] = new_include;
return store != NULL;
}
/**
* \brief Returns a file name on the top of the stack.
* \brief Returns an include on the top of the stack.
*/
char *conf_includes_top(conf_includes_t *includes)
conf_include_t *conf_includes_top(conf_includes_t *includes)
{
if (!includes || includes->free_index == 0)
if (!includes || includes->free_index == 0) {
return NULL;
}
return includes->names[includes->free_index - 1];
return &includes->files[includes->free_index - 1];
}
/**
* \brief Returns a file name on the top of the stack and removes it.
* \brief Returns an include on the top of the stack and removes it.
*/
char *conf_includes_pop(conf_includes_t *includes)
conf_include_t *conf_includes_pop(conf_includes_t *includes)
{
char *result = conf_includes_top(includes);
if (result)
conf_include_t *result = conf_includes_top(includes);
if (result) {
includes->free_index -= 1;
}
return result;
}
......@@ -28,9 +28,18 @@
#define _KNOT_CONF_INCLUDES_H_
#include <stdbool.h>
#include <stdio.h>
/*!
* \brief Structure to store names of files included into the config.
* \brief Structure to hold data for one include in configuration file.
*/
typedef struct {
char *filename;
FILE *handle;
} conf_include_t;
/*!
* \brief Structure to keep config file includes stack.
*/
struct conf_includes;
typedef struct conf_includes conf_includes_t;
......@@ -48,7 +57,7 @@ conf_includes_t *conf_includes_init(int capacity);
void conf_includes_free(conf_includes_t *includes);
/**
* \brief Check if there is a capacity to insert new file..
* \brief Check if there is a capacity to insert new file.
*/
bool conf_includes_can_push(conf_includes_t *includes);
......@@ -65,18 +74,18 @@ bool conf_includes_can_push(conf_includes_t *includes);
bool conf_includes_push(conf_includes_t *includes, const char *filename);
/**
* \brief Returns a file name on the top of the stack.
* \brief Returns an include on the top of the stack.
*
* \return File name on the top of the stack. Do not free it.
*/
char *conf_includes_top(conf_includes_t *includes);
conf_include_t *conf_includes_top(conf_includes_t *includes);
/**
* \brief Returns a file name on the top of the stack and removes it.
* \brief Returns an include on the top of the stack and removes it.
*
* \return File name on the top of the stack. Caller should free the result.
*/
char *conf_includes_pop(conf_includes_t *includes);
conf_include_t *conf_includes_pop(conf_includes_t *includes);
#endif /* _KNOT_CONF_INCLUDES_H_ */
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment