summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2018-06-27 16:52:39 -0400
committerNick Mathewson <nickm@torproject.org>2018-06-27 16:59:56 -0400
commitb9b44bf000735135e1913fd9c22cd6c1547dbdb3 (patch)
treed986c9001e83e3d4c079fd0c4f749101b82cc6e2 /src/common
parent696f6f15697260255146d634e1529202cc4c2b77 (diff)
downloadtor-b9b44bf000735135e1913fd9c22cd6c1547dbdb3.tar.gz
tor-b9b44bf000735135e1913fd9c22cd6c1547dbdb3.zip
Move confline.c to lib/encoding: it is about encoding key-value pairs
Also, move "unescape_string()" to encoding too, since it's about encoding data as C strings.
Diffstat (limited to 'src/common')
-rw-r--r--src/common/confline.c383
-rw-r--r--src/common/confline.h72
-rw-r--r--src/common/include.am2
-rw-r--r--src/common/util.c119
-rw-r--r--src/common/util.h3
5 files changed, 1 insertions, 578 deletions
diff --git a/src/common/confline.c b/src/common/confline.c
deleted file mode 100644
index 80e5994ce8..0000000000
--- a/src/common/confline.c
+++ /dev/null
@@ -1,383 +0,0 @@
-/* Copyright (c) 2001 Matej Pfajfar.
- * Copyright (c) 2001-2004, Roger Dingledine.
- * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2018, The Tor Project, Inc. */
-/* See LICENSE for licensing information */
-
-#include "common/compat.h"
-#include "common/confline.h"
-#include "lib/log/torlog.h"
-#include "common/util.h"
-#include "lib/container/smartlist.h"
-
-/** 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)
-{
- tor_assert(lst);
-
- 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;
-}
-
-/** Helper: allocate a new configuration option mapping 'key' to 'val',
- * and prepend it to *<b>lst</b> */
-void
-config_line_prepend(config_line_t **lst,
- const char *key,
- const char *val)
-{
- tor_assert(lst);
-
- config_line_t *newline;
-
- newline = tor_malloc_zero(sizeof(config_line_t));
- newline->key = tor_strdup(key);
- newline->value = tor_strdup(val);
- newline->next = *lst;
- *lst = newline;
-}
-
-/** Return the first line in <b>lines</b> whose key is exactly <b>key</b>, or
- * NULL if no such key exists.
- *
- * (In options parsing, this is 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;
-}
-
-/** Auxiliary function that does all the work of config_get_lines.
- * <b>recursion_level</b> is the count of how many nested %includes we have.
- * <b>opened_lst</b> will have a list of opened files if provided.
- * Returns the a pointer to the last element of the <b>result</b> in
- * <b>last</b>. */
-int
-config_get_lines_aux(const char *string, config_line_t **result, int extended,
- int allow_include, int *has_include,
- smartlist_t *opened_lst, int recursion_level,
- config_line_t **last,
- include_handler_fn handle_include)
-{
- config_line_t *list = NULL, **next, *list_last = NULL;
- char *k, *v;
- const char *parse_err;
- int include_used = 0;
-
- if (recursion_level > MAX_INCLUDE_RECURSION_LEVEL) {
- log_warn(LD_CONFIG, "Error while parsing configuration: more than %d "
- "nested %%includes.", MAX_INCLUDE_RECURSION_LEVEL);
- return -1;
- }
-
- 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;
- }
- }
-
- if (allow_include && !strcmp(k, "%include") && handle_include) {
- tor_free(k);
- include_used = 1;
-
- config_line_t *include_list;
- if (handle_include(v, recursion_level, extended, &include_list,
- &list_last, opened_lst) < 0) {
- log_warn(LD_CONFIG, "Error reading included configuration "
- "file or directory: \"%s\".", v);
- config_free_lines(list);
- tor_free(v);
- return -1;
- }
- *next = include_list;
- if (list_last)
- next = &list_last->next;
- tor_free(v);
- } else {
- /* 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(**next));
- (*next)->key = k;
- (*next)->value = v;
- (*next)->next = NULL;
- (*next)->command = command;
- list_last = *next;
- next = &((*next)->next);
- }
- } else {
- tor_free(k);
- tor_free(v);
- }
- } while (*string);
-
- if (last) {
- *last = list_last;
- }
- if (has_include) {
- *has_include = include_used;
- }
- *result = list;
- return 0;
-}
-
-/** Same as config_get_lines_include but does not allow %include */
-int
-config_get_lines(const char *string, config_line_t **result, int extended)
-{
- return config_get_lines_aux(string, result, extended, 0, NULL, NULL, 1,
- NULL, NULL);
-}
-
-/**
- * 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);
- }
-}
-
-/** 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 whose keys begin with <b>key</b> (case-insensitive).
- * If <b>key</b> is NULL, do not filter. */
-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 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;
-}
-
-/** Given a string containing part of a configuration file or similar format,
- * advance past comments and whitespace and try to parse a single line. If we
- * parse a line successfully, set *<b>key_out</b> to a new string holding the
- * key portion and *<b>value_out</b> to a new string holding the value portion
- * of the line, and return a pointer to the start of the next line. If we run
- * out of data, return a pointer to the end of the string. If we encounter an
- * error, return NULL and set *<b>err_out</b> (if provided) to an error
- * message.
- */
-const char *
-parse_config_line_from_str_verbose(const char *line, char **key_out,
- char **value_out,
- const char **err_out)
-{
- /*
- See torrc_format.txt for a description of the (silly) format this parses.
- */
- const char *key, *val, *cp;
- int continuation = 0;
-
- tor_assert(key_out);
- tor_assert(value_out);
-
- *key_out = *value_out = NULL;
- key = val = NULL;
- /* Skip until the first keyword. */
- while (1) {
- while (TOR_ISSPACE(*line))
- ++line;
- if (*line == '#') {
- while (*line && *line != '\n')
- ++line;
- } else {
- break;
- }
- }
-
- if (!*line) { /* End of string? */
- *key_out = *value_out = NULL;
- return line;
- }
-
- /* Skip until the next space or \ followed by newline. */
- key = line;
- while (*line && !TOR_ISSPACE(*line) && *line != '#' &&
- ! (line[0] == '\\' && line[1] == '\n'))
- ++line;
- *key_out = tor_strndup(key, line-key);
-
- /* Skip until the value. */
- while (*line == ' ' || *line == '\t')
- ++line;
-
- val = line;
-
- /* Find the end of the line. */
- if (*line == '\"') { // XXX No continuation handling is done here
- if (!(line = unescape_string(line, value_out, NULL))) {
- if (err_out)
- *err_out = "Invalid escape sequence in quoted string";
- return NULL;
- }
- while (*line == ' ' || *line == '\t')
- ++line;
- if (*line == '\r' && *(++line) == '\n')
- ++line;
- if (*line && *line != '#' && *line != '\n') {
- if (err_out)
- *err_out = "Excess data after quoted string";
- return NULL;
- }
- } else {
- /* Look for the end of the line. */
- while (*line && *line != '\n' && (*line != '#' || continuation)) {
- if (*line == '\\' && line[1] == '\n') {
- continuation = 1;
- line += 2;
- } else if (*line == '#') {
- do {
- ++line;
- } while (*line && *line != '\n');
- if (*line == '\n')
- ++line;
- } else {
- ++line;
- }
- }
-
- if (*line == '\n') {
- cp = line++;
- } else {
- cp = line;
- }
- /* Now back cp up to be the last nonspace character */
- while (cp>val && TOR_ISSPACE(*(cp-1)))
- --cp;
-
- tor_assert(cp >= val);
-
- /* Now copy out and decode the value. */
- *value_out = tor_strndup(val, cp-val);
- if (continuation) {
- char *v_out, *v_in;
- v_out = v_in = *value_out;
- while (*v_in) {
- if (*v_in == '#') {
- do {
- ++v_in;
- } while (*v_in && *v_in != '\n');
- if (*v_in == '\n')
- ++v_in;
- } else if (v_in[0] == '\\' && v_in[1] == '\n') {
- v_in += 2;
- } else {
- *v_out++ = *v_in++;
- }
- }
- *v_out = '\0';
- }
- }
-
- if (*line == '#') {
- do {
- ++line;
- } while (*line && *line != '\n');
- }
- while (TOR_ISSPACE(*line)) ++line;
-
- return line;
-}
diff --git a/src/common/confline.h b/src/common/confline.h
deleted file mode 100644
index f03faed5eb..0000000000
--- a/src/common/confline.h
+++ /dev/null
@@ -1,72 +0,0 @@
-/* Copyright (c) 2001 Matej Pfajfar.
- * Copyright (c) 2001-2004, Roger Dingledine.
- * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
- * Copyright (c) 2007-2018, The Tor Project, Inc. */
-/* See LICENSE for licensing information */
-
-#ifndef TOR_CONFLINE_H
-#define TOR_CONFLINE_H
-
-struct smartlist_t;
-
-/** Ordinary configuration line. */
-#define CONFIG_LINE_NORMAL 0
-/** Appends to previous configuration for the same option, even if we
- * would ordinary replace it. */
-#define CONFIG_LINE_APPEND 1
-/* Removes all previous configuration for an option. */
-#define CONFIG_LINE_CLEAR 2
-
-#define MAX_INCLUDE_RECURSION_LEVEL 31
-
-/** A linked list of lines in a config file, or elsewhere */
-typedef struct config_line_t {
- char *key;
- char *value;
- struct config_line_t *next;
-
- /** What special treatment (if any) does this line require? */
- unsigned int command:2;
- /** If true, subsequent assignments to this linelist should replace
- * it, not extend it. Set only on the first item in a linelist in an
- * or_options_t. */
- unsigned int fragile:1;
-} config_line_t;
-
-void config_line_append(config_line_t **lst,
- const char *key, const char *val);
-void config_line_prepend(config_line_t **lst,
- const char *key, const char *val);
-config_line_t *config_lines_dup(const config_line_t *inp);
-config_line_t *config_lines_dup_and_filter(const config_line_t *inp,
- const char *key);
-const config_line_t *config_line_find(const config_line_t *lines,
- const char *key);
-int config_lines_eq(config_line_t *a, config_line_t *b);
-int config_count_key(const config_line_t *a, const char *key);
-void config_free_lines_(config_line_t *front);
-#define config_free_lines(front) \
- do { \
- config_free_lines_(front); \
- (front) = NULL; \
- } while (0)
-const char *parse_config_line_from_str_verbose(const char *line,
- char **key_out, char **value_out,
- const char **err_out);
-
-int config_get_lines(const char *string, struct config_line_t **result,
- int extended);
-
-typedef int (*include_handler_fn)(const char *, int, int,
- struct config_line_t **,
- struct config_line_t **,
- struct smartlist_t *);
-
-int config_get_lines_aux(const char *string, struct 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);
-
-#endif /* !defined(TOR_CONFLINE_H) */
diff --git a/src/common/include.am b/src/common/include.am
index 4fd3284abc..14e7dcb9fc 100644
--- a/src/common/include.am
+++ b/src/common/include.am
@@ -36,7 +36,6 @@ LIBOR_A_SRC = \
src/common/compat.c \
src/common/compat_threads.c \
src/common/compat_time.c \
- src/common/confline.c \
src/common/conffile.c \
src/common/memarea.c \
src/common/util.c \
@@ -81,7 +80,6 @@ COMMONHEADERS = \
src/common/compat_threads.h \
src/common/compat_time.h \
src/common/conffile.h \
- src/common/confline.h \
src/common/handles.h \
src/common/memarea.h \
src/common/procmon.h \
diff --git a/src/common/util.c b/src/common/util.c
index 28efa4a042..f641c1081c 100644
--- a/src/common/util.c
+++ b/src/common/util.c
@@ -453,125 +453,6 @@ tv_to_msec(const struct timeval *tv)
* Filesystem operations.
*/
-#define TOR_ISODIGIT(c) ('0' <= (c) && (c) <= '7')
-
-/** Given a c-style double-quoted escaped string in <b>s</b>, extract and
- * decode its contents into a newly allocated string. On success, assign this
- * string to *<b>result</b>, assign its length to <b>size_out</b> (if
- * provided), and return a pointer to the position in <b>s</b> immediately
- * after the string. On failure, return NULL.
- */
-const char *
-unescape_string(const char *s, char **result, size_t *size_out)
-{
- const char *cp;
- char *out;
- if (s[0] != '\"')
- return NULL;
- cp = s+1;
- while (1) {
- switch (*cp) {
- case '\0':
- case '\n':
- return NULL;
- case '\"':
- goto end_of_loop;
- case '\\':
- if (cp[1] == 'x' || cp[1] == 'X') {
- if (!(TOR_ISXDIGIT(cp[2]) && TOR_ISXDIGIT(cp[3])))
- return NULL;
- cp += 4;
- } else if (TOR_ISODIGIT(cp[1])) {
- cp += 2;
- if (TOR_ISODIGIT(*cp)) ++cp;
- if (TOR_ISODIGIT(*cp)) ++cp;
- } else if (cp[1] == 'n' || cp[1] == 'r' || cp[1] == 't' || cp[1] == '"'
- || cp[1] == '\\' || cp[1] == '\'') {
- cp += 2;
- } else {
- return NULL;
- }
- break;
- default:
- ++cp;
- break;
- }
- }
- end_of_loop:
- out = *result = tor_malloc(cp-s + 1);
- cp = s+1;
- while (1) {
- switch (*cp)
- {
- case '\"':
- *out = '\0';
- if (size_out) *size_out = out - *result;
- return cp+1;
-
- /* LCOV_EXCL_START -- we caught this in parse_config_from_line. */
- case '\0':
- tor_fragile_assert();
- tor_free(*result);
- return NULL;
- /* LCOV_EXCL_STOP */
- case '\\':
- switch (cp[1])
- {
- case 'n': *out++ = '\n'; cp += 2; break;
- case 'r': *out++ = '\r'; cp += 2; break;
- case 't': *out++ = '\t'; cp += 2; break;
- case 'x': case 'X':
- {
- int x1, x2;
-
- x1 = hex_decode_digit(cp[2]);
- x2 = hex_decode_digit(cp[3]);
- if (x1 == -1 || x2 == -1) {
- /* LCOV_EXCL_START */
- /* we caught this above in the initial loop. */
- tor_assert_nonfatal_unreached();
- tor_free(*result);
- return NULL;
- /* LCOV_EXCL_STOP */
- }
-
- *out++ = ((x1<<4) + x2);
- cp += 4;
- }
- break;
- case '0': case '1': case '2': case '3': case '4': case '5':
- case '6': case '7':
- {
- int n = cp[1]-'0';
- cp += 2;
- if (TOR_ISODIGIT(*cp)) { n = n*8 + *cp-'0'; cp++; }
- if (TOR_ISODIGIT(*cp)) { n = n*8 + *cp-'0'; cp++; }
- if (n > 255) { tor_free(*result); return NULL; }
- *out++ = (char)n;
- }
- break;
- case '\'':
- case '\"':
- case '\\':
- case '\?':
- *out++ = cp[1];
- cp += 2;
- break;
-
- /* LCOV_EXCL_START */
- default:
- /* we caught this above in the initial loop. */
- tor_assert_nonfatal_unreached();
- tor_free(*result); return NULL;
- /* LCOV_EXCL_STOP */
- }
- break;
- default:
- *out++ = *cp++;
- }
- }
-}
-
/* =====
* Process helpers
* ===== */
diff --git a/src/common/util.h b/src/common/util.h
index 7547b8708a..549bbf9aaa 100644
--- a/src/common/util.h
+++ b/src/common/util.h
@@ -39,6 +39,7 @@
#include "lib/fs/files.h"
#include "lib/fs/path.h"
#include "lib/encoding/time_fmt.h"
+#include "lib/encoding/cstring.h"
void tor_log_mallinfo(int severity);
@@ -102,8 +103,6 @@ const char *stream_status_to_string(enum stream_status stream_status);
enum stream_status get_string_from_pipe(int fd, char *buf, size_t count);
-const char *unescape_string(const char *s, char **result, size_t *size_out);
-
/* Process helpers */
void start_daemon(void);
void finish_daemon(const char *desired_cwd);