diff options
author | Nick Mathewson <nickm@torproject.org> | 2007-02-10 21:26:29 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2007-02-10 21:26:29 +0000 |
commit | 24e7b9b9839a55c2a02c42437e8167db529ead5a (patch) | |
tree | 4c8e117d67b80d324165d2e8dcfef4d4041d42d8 | |
parent | 2c521d9804382b7ea2d5835e91948aa0c6862772 (diff) | |
download | tor-24e7b9b9839a55c2a02c42437e8167db529ead5a.tar.gz tor-24e7b9b9839a55c2a02c42437e8167db529ead5a.zip |
r12213@Kushana: nickm | 2007-02-10 16:25:39 -0500
Refactor setconf implementation to be a little slower, but far less error prone.
svn:r9549
-rw-r--r-- | src/or/control.c | 43 |
1 files changed, 29 insertions, 14 deletions
diff --git a/src/or/control.c b/src/or/control.c index 42b04b6dd3..a450d947df 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -802,40 +802,55 @@ control_setconf_helper(control_connection_t *conn, uint32_t len, char *body, int v0 = STATE_IS_V0(conn->_base.state); if (!v0) { - char *config = tor_malloc(len+1); - char *outp = config; + char *config; + smartlist_t *entries = smartlist_create(); + /* We have a string, "body", of the format '(key(=val|="val")?)' entries + * separated by space. break it into a list of configuration entries. */ while (*body) { char *eq = body; + char *key; + char *entry; while (!TOR_ISSPACE(*eq) && *eq != '=') ++eq; - memcpy(outp, body, eq-body); - outp += (eq-body); + key = tor_strndup(body, eq-body); body = eq+1; if (*eq == '=') { - *outp++ = ' '; + char *val; + size_t val_len; + size_t ent_len; if (*body != '\"') { + char *val_start = body; while (!TOR_ISSPACE(*body)) - *outp++ = *body++; + body++; + val = tor_strndup(val_start, body-val_start); + val_len = strlen(val); } else { - char *val; - size_t val_len; body = (char*)get_escaped_string(body, (len - (body-start)), &val, &val_len); if (!body) { connection_write_str_to_buf("551 Couldn't parse string\r\n", conn); - tor_free(config); + SMARTLIST_FOREACH(entries, char *, cp, tor_free(cp)); + smartlist_free(entries); return 0; } - memcpy(outp, val, val_len); - outp += val_len; - tor_free(val); } + ent_len = strlen(key)+val_len+3; + entry = tor_malloc(ent_len+1); + tor_snprintf(entry, ent_len, "%s %s", key, val); + tor_free(key); + tor_free(val); + } else { + entry = key; } + smartlist_add(entries, entry); while (TOR_ISSPACE(*body)) ++body; - *outp++ = '\n'; } - *outp = '\0'; + + smartlist_add(entries, tor_strdup("")); + config = smartlist_join_strings(entries, "\n", 0, NULL); + SMARTLIST_FOREACH(entries, char *, cp, tor_free(cp)); + smartlist_free(entries); if (config_get_lines(config, &lines) < 0) { log_warn(LD_CONTROL,"Controller gave us config lines we can't parse."); |