41 newline->key = tor_strdup(key);
42 newline->value = tor_strdup(val);
45 lst = &((*lst)->next);
62 newline->key = tor_strdup(key);
63 newline->value = tor_strdup(val);
78 for (cl = lines; cl; cl = cl->next) {
79 if (!strcmp(cl->key, key))
91 for (cl = lines; cl; cl = cl->next) {
92 if (!strcasecmp(cl->key, key))
105 int allow_include,
int *has_include,
106 struct smartlist_t *opened_lst,
int recursion_level,
108 include_handler_fn handle_include)
112 const char *parse_err;
113 int include_used = 0;
115 if (recursion_level > MAX_INCLUDE_RECURSION_LEVEL) {
116 log_warn(
LD_CONFIG,
"Error while parsing configuration: more than %d "
117 "nested %%includes.", MAX_INCLUDE_RECURSION_LEVEL);
126 log_warn(
LD_CONFIG,
"Error while parsing configuration: %s",
127 parse_err?parse_err:
"<unknown>");
128 config_free_lines(list);
137 char *k_new = tor_strdup(k+1);
141 }
else if (k[0] ==
'/') {
142 char *k_new = tor_strdup(k+1);
151 if (allow_include && !strcmp(k,
"%include") && handle_include) {
154 log_notice(
LD_CONFIG,
"Processing configuration path \"%s\" at "
155 "recursion level %d.", v, recursion_level);
158 if (handle_include(v, recursion_level, extended, &include_list,
159 &list_last, opened_lst) < 0) {
160 log_warn(
LD_CONFIG,
"Error reading included configuration "
161 "file or directory: \"%s\".", v);
162 config_free_lines(list);
166 *next = include_list;
168 next = &list_last->next;
174 *next = tor_malloc_zero(
sizeof(**next));
177 (*next)->next = NULL;
180 next = &((*next)->next);
192 *has_include = include_used;
246 (*next_out)->key = tor_strdup(inp->key);
247 (*next_out)->value = tor_strdup(inp->value);
249 next_out = &((*next_out)->next);
268 if (BUG(inp == NULL))
270 if (BUG(strcasecmp(inp->key, header)))
276 while (*ptr && strcasecmp((*ptr)->key, header)) {
290 if (strcasecmp(a->key, b->key) || strcmp(a->value, b->value))
306 if (!strcasecmp(a->key, key)) {
326 const char **err_out)
331 const char *key, *val, *cp;
332 int continuation = 0;
337 *key_out = *value_out = NULL;
341 while (TOR_ISSPACE(*line))
344 while (*line && *line !=
'\n')
352 *key_out = *value_out = NULL;
358 while (*line && !TOR_ISSPACE(*line) && *line !=
'#' &&
359 ! (line[0] ==
'\\' && line[1] ==
'\n'))
361 *key_out = tor_strndup(key, line-key);
364 while (*line ==
' ' || *line ==
'\t')
373 *err_out =
"Invalid escape sequence in quoted string";
376 while (*line ==
' ' || *line ==
'\t')
378 if (*line ==
'\r' && *(++line) ==
'\n')
380 if (*line && *line !=
'#' && *line !=
'\n') {
382 *err_out =
"Excess data after quoted string";
387 while (*line && *line !=
'\n' && (*line !=
'#' || continuation)) {
388 if (*line ==
'\\' && line[1] ==
'\n') {
391 }
else if (*line ==
'#') {
394 }
while (*line && *line !=
'\n');
408 while (cp>val && TOR_ISSPACE(*(cp-1)))
414 *value_out = tor_strndup(val, cp-val);
417 v_out = v_in = *value_out;
422 }
while (*v_in && *v_in !=
'\n');
425 }
else if (v_in[0] ==
'\\' && v_in[1] ==
'\n') {
438 }
while (*line && *line !=
'\n');
440 while (TOR_ISSPACE(*line)) ++line;
Locale-independent character-type inspection (header)
Header for compat_string.c.
tor_cmdline_mode_t command
void config_line_prepend(config_line_t **lst, const char *key, const char *val)
const config_line_t * config_line_find(const config_line_t *lines, const char *key)
config_line_t * config_lines_dup_and_filter(const config_line_t *inp, const char *key)
config_line_t * config_lines_partition(config_line_t *inp, const char *header)
int config_get_lines_aux(const char *string, config_line_t **result, int extended, int allow_include, int *has_include, struct smartlist_t *opened_lst, int recursion_level, config_line_t **last, include_handler_fn handle_include)
void config_free_lines_(config_line_t *front)
const char * parse_config_line_from_str_verbose(const char *line, char **key_out, char **value_out, const char **err_out)
int config_count_key(const config_line_t *a, const char *key)
config_line_t * config_lines_dup(const config_line_t *inp)
void config_line_append(config_line_t **lst, const char *key, const char *val)
int config_get_lines(const char *string, config_line_t **result, int extended)
const config_line_t * config_line_find_case(const config_line_t *lines, const char *key)
int config_lines_eq(const config_line_t *a, const config_line_t *b)
#define CONFIG_LINE_APPEND
#define CONFIG_LINE_NORMAL
const char * unescape_string(const char *s, char **result, size_t *size_out)
Headers for util_malloc.c.
Macros to manage assertions, fatal and non-fatal.
int strcasecmpstart(const char *s1, const char *s2)
Header for util_string.c.