|
@@ -31,8 +31,6 @@ static int config_parse_msec_interval(const char *s, int *ok);
|
|
|
static int config_parse_interval(const char *s, int *ok);
|
|
|
static void config_reset(const config_format_t *fmt, void *options,
|
|
|
const config_var_t *var, int use_defaults);
|
|
|
-static config_line_t *config_lines_dup_and_filter(const config_line_t *inp,
|
|
|
- const char *key);
|
|
|
|
|
|
/** Allocate an empty configuration object of a given format type. */
|
|
|
void *
|
|
@@ -80,120 +78,6 @@ config_expand_abbrev(const config_format_t *fmt, const char *option,
|
|
|
return option;
|
|
|
}
|
|
|
|
|
|
-/** Helper: allocate a new configuration option mapping 'key' to 'val',
|
|
|
- * append it to *<b>lst</b>. */
|
|
|
-void
|
|
|
-config_line_append(config_line_t **lst,
|
|
|
- const char *key,
|
|
|
- const char *val)
|
|
|
-{
|
|
|
- config_line_t *newline;
|
|
|
-
|
|
|
- newline = tor_malloc_zero(sizeof(config_line_t));
|
|
|
- newline->key = tor_strdup(key);
|
|
|
- newline->value = tor_strdup(val);
|
|
|
- newline->next = NULL;
|
|
|
- while (*lst)
|
|
|
- lst = &((*lst)->next);
|
|
|
-
|
|
|
- (*lst) = newline;
|
|
|
-}
|
|
|
-
|
|
|
-/** Return the line in <b>lines</b> whose key is exactly <b>key</b>, or NULL
|
|
|
- * if no such key exists. For handling commandline-only options only; other
|
|
|
- * options should be looked up in the appropriate data structure. */
|
|
|
-const config_line_t *
|
|
|
-config_line_find(const config_line_t *lines,
|
|
|
- const char *key)
|
|
|
-{
|
|
|
- const config_line_t *cl;
|
|
|
- for (cl = lines; cl; cl = cl->next) {
|
|
|
- if (!strcmp(cl->key, key))
|
|
|
- return cl;
|
|
|
- }
|
|
|
- return NULL;
|
|
|
-}
|
|
|
-
|
|
|
-/** Helper: parse the config string and strdup into key/value
|
|
|
- * strings. Set *result to the list, or NULL if parsing the string
|
|
|
- * failed. Return 0 on success, -1 on failure. Warn and ignore any
|
|
|
- * misformatted lines.
|
|
|
- *
|
|
|
- * If <b>extended</b> is set, then treat keys beginning with / and with + as
|
|
|
- * indicating "clear" and "append" respectively. */
|
|
|
-int
|
|
|
-config_get_lines(const char *string, config_line_t **result, int extended)
|
|
|
-{
|
|
|
- config_line_t *list = NULL, **next;
|
|
|
- char *k, *v;
|
|
|
- const char *parse_err;
|
|
|
-
|
|
|
- next = &list;
|
|
|
- do {
|
|
|
- k = v = NULL;
|
|
|
- string = parse_config_line_from_str_verbose(string, &k, &v, &parse_err);
|
|
|
- if (!string) {
|
|
|
- log_warn(LD_CONFIG, "Error while parsing configuration: %s",
|
|
|
- parse_err?parse_err:"<unknown>");
|
|
|
- config_free_lines(list);
|
|
|
- tor_free(k);
|
|
|
- tor_free(v);
|
|
|
- return -1;
|
|
|
- }
|
|
|
- if (k && v) {
|
|
|
- unsigned command = CONFIG_LINE_NORMAL;
|
|
|
- if (extended) {
|
|
|
- if (k[0] == '+') {
|
|
|
- char *k_new = tor_strdup(k+1);
|
|
|
- tor_free(k);
|
|
|
- k = k_new;
|
|
|
- command = CONFIG_LINE_APPEND;
|
|
|
- } else if (k[0] == '/') {
|
|
|
- char *k_new = tor_strdup(k+1);
|
|
|
- tor_free(k);
|
|
|
- k = k_new;
|
|
|
- tor_free(v);
|
|
|
- v = tor_strdup("");
|
|
|
- command = CONFIG_LINE_CLEAR;
|
|
|
- }
|
|
|
- }
|
|
|
- /* This list can get long, so we keep a pointer to the end of it
|
|
|
- * rather than using config_line_append over and over and getting
|
|
|
- * n^2 performance. */
|
|
|
- *next = tor_malloc_zero(sizeof(config_line_t));
|
|
|
- (*next)->key = k;
|
|
|
- (*next)->value = v;
|
|
|
- (*next)->next = NULL;
|
|
|
- (*next)->command = command;
|
|
|
- next = &((*next)->next);
|
|
|
- } else {
|
|
|
- tor_free(k);
|
|
|
- tor_free(v);
|
|
|
- }
|
|
|
- } while (*string);
|
|
|
-
|
|
|
- *result = list;
|
|
|
- return 0;
|
|
|
-}
|
|
|
-
|
|
|
-/**
|
|
|
- * Free all the configuration lines on the linked list <b>front</b>.
|
|
|
- */
|
|
|
-void
|
|
|
-config_free_lines(config_line_t *front)
|
|
|
-{
|
|
|
- config_line_t *tmp;
|
|
|
-
|
|
|
- while (front) {
|
|
|
- tmp = front;
|
|
|
- front = tmp->next;
|
|
|
-
|
|
|
- tor_free(tmp->key);
|
|
|
- tor_free(tmp->value);
|
|
|
- tor_free(tmp);
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
/** If <b>key</b> is a deprecated configuration option, return the message
|
|
|
* explaining why it is deprecated (which may be an empty string). Return NULL
|
|
|
* if it is not deprecated. The <b>key</b> field must be fully expanded. */
|
|
@@ -633,36 +517,6 @@ config_value_needs_escape(const char *value)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-/** Return a newly allocated deep copy of the lines in <b>inp</b>. */
|
|
|
-config_line_t *
|
|
|
-config_lines_dup(const config_line_t *inp)
|
|
|
-{
|
|
|
- return config_lines_dup_and_filter(inp, NULL);
|
|
|
-}
|
|
|
-
|
|
|
-/** Return a newly allocated deep copy of the lines in <b>inp</b>,
|
|
|
- * but only the ones that match <b>key</b>. */
|
|
|
-static config_line_t *
|
|
|
-config_lines_dup_and_filter(const config_line_t *inp,
|
|
|
- const char *key)
|
|
|
-{
|
|
|
- config_line_t *result = NULL;
|
|
|
- config_line_t **next_out = &result;
|
|
|
- while (inp) {
|
|
|
- if (key && strcasecmpstart(inp->key, key)) {
|
|
|
- inp = inp->next;
|
|
|
- continue;
|
|
|
- }
|
|
|
- *next_out = tor_malloc_zero(sizeof(config_line_t));
|
|
|
- (*next_out)->key = tor_strdup(inp->key);
|
|
|
- (*next_out)->value = tor_strdup(inp->value);
|
|
|
- inp = inp->next;
|
|
|
- next_out = &((*next_out)->next);
|
|
|
- }
|
|
|
- (*next_out) = NULL;
|
|
|
- return result;
|
|
|
-}
|
|
|
-
|
|
|
/** Return newly allocated line or lines corresponding to <b>key</b> in the
|
|
|
* configuration <b>options</b>. If <b>escape_val</b> is true and a
|
|
|
* value needs to be quoted before it's put in a config file, quote and
|
|
@@ -1028,36 +882,6 @@ config_free(const config_format_t *fmt, void *options)
|
|
|
tor_free(options);
|
|
|
}
|
|
|
|
|
|
-/** Return true iff a and b contain identical keys and values in identical
|
|
|
- * order. */
|
|
|
-int
|
|
|
-config_lines_eq(config_line_t *a, config_line_t *b)
|
|
|
-{
|
|
|
- while (a && b) {
|
|
|
- if (strcasecmp(a->key, b->key) || strcmp(a->value, b->value))
|
|
|
- return 0;
|
|
|
- a = a->next;
|
|
|
- b = b->next;
|
|
|
- }
|
|
|
- if (a || b)
|
|
|
- return 0;
|
|
|
- return 1;
|
|
|
-}
|
|
|
-
|
|
|
-/** Return the number of lines in <b>a</b> whose key is <b>key</b>. */
|
|
|
-int
|
|
|
-config_count_key(const config_line_t *a, const char *key)
|
|
|
-{
|
|
|
- int n = 0;
|
|
|
- while (a) {
|
|
|
- if (!strcasecmp(a->key, key)) {
|
|
|
- ++n;
|
|
|
- }
|
|
|
- a = a->next;
|
|
|
- }
|
|
|
- return n;
|
|
|
-}
|
|
|
-
|
|
|
/** Return true iff the option <b>name</b> has the same value in <b>o1</b>
|
|
|
* and <b>o2</b>. Must not be called for LINELIST_S or OBSOLETE options.
|
|
|
*/
|