Navigation Menu

Skip to content

Commit

Permalink
In order to support a control action for setting/removing mod_tls-rel…
Browse files Browse the repository at this point in the history
…ated

configuration directives, the Parser API needed to have some private/internal
functions exposed.
  • Loading branch information
Castaglia committed Aug 8, 2016
1 parent 1ba1632 commit 8fbb158
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 30 deletions.
40 changes: 26 additions & 14 deletions include/parser.h
@@ -1,6 +1,6 @@
/*
* ProFTPD - FTP server daemon
* Copyright (c) 2004-2015 The ProFTPD Project team
* Copyright (c) 2004-2016 The ProFTPD Project team
*
* 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
Expand Down Expand Up @@ -39,6 +39,12 @@ int pr_parser_prepare(pool *p, xaset_t **parsed_servers);
*/
int pr_parser_cleanup(void);

/* Called to push a "start-of-context" configuration marker onto the
* parser stack. The name of the configuration context (.e.g "Directory"
* or "Anonymous") is provided by the name parameter.
*/
config_rec *pr_parser_config_ctxt_open(const char *name);

/* Called to push an "end-of-context" configuration marker onto the
* parser stack. If the parser determines that the configuration
* context being closed is empty, it will remove the entire context from
Expand All @@ -47,17 +53,17 @@ int pr_parser_cleanup(void);
*/
config_rec *pr_parser_config_ctxt_close(int *isempty);

/* Push the config_rec onto the parser stack directly. This function can
* be used, instead of the open/close semantics, for cases where the config_rec
* is constructed by means other than file parsing.
*/
int pr_parser_config_ctxt_push(config_rec *c);

/* Returns a pointer to the current configuration record on the parser
* configuration stack.
*/
config_rec *pr_parser_config_ctxt_get(void);

/* Called to push a "start-of-context" configuration marker onto the
* parser stack. The name of the configuration context (.e.g "Directory"
* or "Anonymous") is provided by the name parameter.
*/
config_rec *pr_parser_config_ctxt_open(const char *name);

/* Returns the line number of the configuration stream being parsed. */
unsigned int pr_parser_get_lineno(void);

Expand Down Expand Up @@ -100,23 +106,29 @@ cmd_rec *pr_parser_parse_line(pool *p, const char *text, size_t text_len);
*/
char *pr_parser_read_line(char *buf, size_t bufsz);

/* Called to push a "start-of-server" configuration marker onto the
* parser stack. The name of the server context, usually a string
* containing a DNS name or an IP address, is provided by the addrstr
* parameter.
*/
server_rec *pr_parser_server_ctxt_open(const char *addrstr);

/* Called to push an "end-of-server" configuration record onto the
* parser stack. If the parser determines that the server context being
* closed is empty, it will remove the entire context from the parser stacks:
* empty contexts are superfluous.
*/
server_rec *pr_parser_server_ctxt_close(void);

/* Push the server_rec onto the parser stack directly. This function can
* be used, instead of the open/close semantics, for cases where the server_rec
* is constructed by means other than file parsing.
*/
int pr_parser_server_ctxt_push(server_rec *s);

/* Returns a pointer to the current server record on the parser server
* stack.
*/
server_rec *pr_parser_server_ctxt_get(void);

/* Called to push a "start-of-server" configuration marker onto the
* parser stack. The name of the server context, usually a string
* containing a DNS name or an IP address, is provided by the addrstr
* parameter.
*/
server_rec *pr_parser_server_ctxt_open(const char *addrstr);

#endif /* PR_PARSER_H */
59 changes: 43 additions & 16 deletions src/parser.c
Expand Up @@ -62,16 +62,6 @@ static struct config_src *parser_sources = NULL;
/* Private functions
*/

static void add_config_ctxt(config_rec *c) {
if (!*parser_curr_config) {
*parser_curr_config = c;

} else {
parser_curr_config = (config_rec **) push_array(parser_confstack);
*parser_curr_config = c;
}
}

static struct config_src *add_config_source(pr_fh_t *fh) {
pool *p = pr_pool_create_sz(parser_pool, PARSER_CONFIG_SRC_POOL_SZ);
struct config_src *cs = pcalloc(p, sizeof(struct config_src));
Expand Down Expand Up @@ -316,10 +306,32 @@ config_rec *pr_parser_config_ctxt_open(const char *name) {
}
}

add_config_ctxt(c);
(void) pr_parser_config_ctxt_push(c);
return c;
}

int pr_parser_config_ctxt_push(config_rec *c) {
if (c == NULL) {
errno = EINVAL;
return -1;
}

if (parser_confstack == NULL) {
errno = EPERM;
return -1;
}

if (!*parser_curr_config) {
*parser_curr_config = c;

} else {
parser_curr_config = (config_rec **) push_array(parser_confstack);
*parser_curr_config = c;
}

return 0;
}

unsigned int pr_parser_get_lineno(void) {
return parser_curr_lineno;
}
Expand Down Expand Up @@ -403,8 +415,8 @@ int pr_parser_parse_file(pool *p, const char *path, config_rec *start,
*/
cs = add_config_source(fh);

if (start) {
add_config_ctxt(start);
if (start != NULL) {
(void) pr_parser_config_ctxt_push(start);
}

bufsz = PR_TUNABLE_PARSER_BUFFER_SIZE;
Expand Down Expand Up @@ -770,6 +782,23 @@ server_rec *pr_parser_server_ctxt_get(void) {
return NULL;
}

int pr_parser_server_ctxt_push(server_rec *s) {
if (s == NULL) {
errno = EINVAL;
return -1;
}

if (parser_servstack == NULL) {
errno = EPERM;
return -1;
}

parser_curr_server = (server_rec **) push_array(parser_servstack);
*parser_curr_server = s;

return 0;
}

server_rec *pr_parser_server_ctxt_open(const char *addrstr) {
server_rec *s;
pool *p;
Expand Down Expand Up @@ -802,8 +831,6 @@ server_rec *pr_parser_server_ctxt_open(const char *addrstr) {
/* Default server port */
s->ServerPort = pr_inet_getservport(s->pool, "ftp", "tcp");

parser_curr_server = (server_rec **) push_array(parser_servstack);
*parser_curr_server = s;

(void) pr_parser_server_ctxt_push(s);
return s;
}
68 changes: 68 additions & 0 deletions tests/api/parser.c
Expand Up @@ -112,6 +112,39 @@ START_TEST (parser_server_ctxt_test) {
}
END_TEST

START_TEST (parser_server_ctxt_push_test) {
int res;
server_rec *ctx, *ctx2;

res = pr_parser_server_ctxt_push(NULL);
fail_unless(res < 0, "Failed to handle null argument");
fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
strerror(errno), errno);

ctx = pcalloc(p, sizeof(server_rec));

mark_point();
res = pr_parser_server_ctxt_push(ctx);
fail_unless(res < 0, "Failed to handle unprepared parser");
fail_unless(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
strerror(errno), errno);

pr_parser_prepare(p, NULL);

mark_point();
res = pr_parser_server_ctxt_push(ctx);
fail_unless(res == 0, "Failed to push server rec: %s", strerror(errno));

mark_point();
ctx2 = pr_parser_server_ctxt_get();
fail_unless(ctx2 != NULL, "Failed to get current server context: %s",
strerror(errno));
fail_unless(ctx2 == ctx, "Expected server context %p, got %p", ctx, ctx2);

pr_parser_cleanup();
}
END_TEST

START_TEST (parser_config_ctxt_test) {
int is_empty = FALSE;
config_rec *ctx, *res;
Expand Down Expand Up @@ -148,6 +181,39 @@ START_TEST (parser_config_ctxt_test) {
}
END_TEST

START_TEST (parser_config_ctxt_push_test) {
int res;
config_rec *ctx, *ctx2;

res = pr_parser_config_ctxt_push(NULL);
fail_unless(res < 0, "Failed to handle null argument");
fail_unless(errno == EINVAL, "Expected EINVAL (%d), got %s (%d)", EINVAL,
strerror(errno), errno);

ctx = pcalloc(p, sizeof(config_rec));

mark_point();
res = pr_parser_config_ctxt_push(ctx);
fail_unless(res < 0, "Failed to handle unprepared parser");
fail_unless(errno == EPERM, "Expected EPERM (%d), got %s (%d)", EPERM,
strerror(errno), errno);

pr_parser_prepare(p, NULL);

mark_point();
res = pr_parser_config_ctxt_push(ctx);
fail_unless(res == 0, "Failed to push config rec: %s", strerror(errno));

mark_point();
ctx2 = pr_parser_config_ctxt_get();
fail_unless(ctx2 != NULL, "Failed to get current config context: %s",
strerror(errno));
fail_unless(ctx2 == ctx, "Expected config context %p, got %p", ctx, ctx2);

pr_parser_cleanup();
}
END_TEST

START_TEST (parser_get_lineno_test) {
unsigned int res;

Expand Down Expand Up @@ -373,7 +439,9 @@ Suite *tests_get_parser_suite(void) {

tcase_add_test(testcase, parser_prepare_test);
tcase_add_test(testcase, parser_server_ctxt_test);
tcase_add_test(testcase, parser_server_ctxt_push_test);
tcase_add_test(testcase, parser_config_ctxt_test);
tcase_add_test(testcase, parser_config_ctxt_push_test);
tcase_add_test(testcase, parser_get_lineno_test);
tcase_add_test(testcase, parser_read_line_test);
tcase_add_test(testcase, parser_parse_line_test);
Expand Down

0 comments on commit 8fbb158

Please sign in to comment.