Skip to content

Commit

Permalink
Add $INCLUDE callback for dependency tracking
Browse files Browse the repository at this point in the history
  • Loading branch information
k0ekk0ek committed Aug 21, 2024
1 parent 3b80948 commit 9e91478
Show file tree
Hide file tree
Showing 3 changed files with 133 additions and 0 deletions.
16 changes: 16 additions & 0 deletions include/zone.h
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,18 @@ typedef int32_t(*zone_accept_t)(
const uint8_t *, // rdata
void *); // user data

/**
* @brief Signature of callback function invoked on $INCLUDE.
*
* Signal file name in $INCLUDE directive to application. Useful for
* dependency tracking, etc.
*/
typedef int32_t(*zone_include_t)(
zone_parser_t *,
const char *, // name in $INCLUDE entry
const char *, // fully qualified path
void *); // user data

/**
* @brief Available configuration options.
*/
Expand Down Expand Up @@ -411,6 +423,10 @@ typedef struct {
/** Callback invoked for each RR. */
zone_accept_t callback;
} accept;
struct {
/** Callback invoked for each $INCLUDE entry. */
zone_include_t callback;
} include;
} zone_options_t;

/**
Expand Down
10 changes: 10 additions & 0 deletions src/generic/format.h
Original file line number Diff line number Diff line change
Expand Up @@ -299,6 +299,16 @@ static really_inline int32_t parse_dollar_include(
}
}

// signal $INCLUDE to application
if (parser->options.include.callback) {
code = parser->options.include.callback(
parser, file->name, file->path, parser->user_data);
if (code) {
zone_close_file(parser, file);
return code;
}
}

adjust_line_count(parser->file);
parser->file = file;
return 0;
Expand Down
107 changes: 107 additions & 0 deletions tests/include.c
Original file line number Diff line number Diff line change
Expand Up @@ -609,3 +609,110 @@ diagnostic_pop()
(void)rmdir(dir2);
#endif
}


struct file_list {
size_t index;
size_t count;
char **paths;
};

static int32_t track_include_cb(
zone_parser_t *parser,
const char *name,
const char *path,
void *user_data)
{
struct file_list *list = (struct file_list *)user_data;

(void)parser;
(void)path;

fprintf(stderr, "INCLUDED: %s (%s)\n", name, path);

if (list->index >= list->count)
return ZONE_SYNTAX_ERROR;
if (strcmp(name, list->paths[list->index++]) != 0)
return ZONE_SYNTAX_ERROR;
return 0;
}

static int32_t track_accept_cb(
zone_parser_t *parser,
const zone_name_t *owner,
uint16_t type,
uint16_t class,
uint32_t ttl,
uint16_t rdlength,
const uint8_t *rdata,
void *user_data)
{
(void)parser;
(void)owner;
(void)type;
(void)class;
(void)ttl;
(void)rdlength;
(void)rdata;
(void)user_data;
return 0;
}

/*!cmocka */
void track_includes(void **state)
{
char *paths[2] = { NULL, NULL };
FILE *handles[2] = { NULL, NULL };
struct file_list list = { 0, 2, paths };
(void)state;

static const char fmt[] =
"$INCLUDE \"%s\"\n"
"example A 192.0.2.1\n";

paths[0] = get_tempnam(NULL, "zone");
assert_non_null(paths[0]);
handles[0] = fopen(paths[0], "wb");
assert_non_null(handles[0]);
paths[1] = get_tempnam(NULL, "zone");
assert_non_null(paths[1]);
handles[1] = fopen(paths[1], "wb");
assert_non_null(handles[1]);

fprintf(handles[0], fmt, paths[1]);
(void)fflush(handles[0]);
(void)fclose(handles[0]);
fputs("example A 192.0.2.1\n", handles[1]);
(void)fflush(handles[1]);
(void)fclose(handles[1]);

char buf[128];
int len = snprintf(buf, sizeof(buf), fmt, paths[0]);
assert_true(len > 0);

char *str = malloc((size_t)len + ZONE_BLOCK_SIZE + 1);
assert_non_null(str);
(void)snprintf(str, (size_t)len+1, fmt, paths[0]);

zone_parser_t parser;
zone_options_t options;
zone_name_buffer_t name;
zone_rdata_buffer_t rdata;
zone_buffers_t buffers = { 1, &name, &rdata };

memset(&options, 0, sizeof(options));
options.include.callback = &track_include_cb;
options.accept.callback = &track_accept_cb;
options.origin.octets = origin;
options.origin.length = sizeof(origin);
options.default_ttl = 3600;
options.default_class = 1;

int32_t code = zone_parse_string(&parser, &options, &buffers, str, len, &list);
assert_int_equal(code, ZONE_SUCCESS);
assert_int_equal(list.index, 2);

free(str);
free(paths[0]);
free(paths[1]);
}

0 comments on commit 9e91478

Please sign in to comment.