diff options
author | Nick Mathewson <nickm@torproject.org> | 2006-08-25 21:01:56 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2006-08-25 21:01:56 +0000 |
commit | c82c4a9e8b03e7430c5783256af1d24e2c9b3cdd (patch) | |
tree | 2401c761c410e5df0305afb436981077d61b102d /src/or/config.c | |
parent | 0649fa14c1618fe98116dfc07d921f89f23d968e (diff) | |
download | tor-c82c4a9e8b03e7430c5783256af1d24e2c9b3cdd.tar.gz tor-c82c4a9e8b03e7430c5783256af1d24e2c9b3cdd.zip |
r8572@Kushana: nickm | 2006-08-25 16:35:49 -0400
Fix for bug 308: When we have a state file we cannot parse, tell the user, and move it aside.
svn:r8224
Diffstat (limited to 'src/or/config.c')
-rw-r--r-- | src/or/config.c | 60 |
1 files changed, 49 insertions, 11 deletions
diff --git a/src/or/config.c b/src/or/config.c index 7beca558b3..74b2ca607b 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -3776,7 +3776,7 @@ or_state_load(void) or_state_t *new_state = NULL; char *contents = NULL, *fname; char *errmsg = NULL; - int r = -1; + int r = -1, badstate = 0; fname = get_or_state_fname(); switch (file_status(fname)) { @@ -3806,30 +3806,68 @@ or_state_load(void) lines, 0, 0, &errmsg); config_free_lines(lines); if (assign_retval<0) - goto done; + badstate = 1; + if (errmsg) { + log_warn(LD_GENERAL, "%s", errmsg); + tor_free(errmsg); + } } - if (or_state_validate(NULL, new_state, 1, &errmsg) < 0) { - goto done; + if (!badstate && or_state_validate(NULL, new_state, 1, &errmsg) < 0) + badstate = 1; + + if (errmsg) { + log_warn(LD_GENERAL, "%s", errmsg); + tor_free(errmsg); } - if (contents) + if (badstate && !contents) { + log_err(LD_BUG, "Uh oh. We couldn't even validate our own default state. " + "This is a bug in Tor."); + goto done; + } else if (badstate && contents) { + int i; + file_status_t status; + size_t len = strlen(fname)+16; + char *fname2 = tor_malloc(len); + for (i = 0; i < 10000; ++i) { + tor_snprintf(fname2, len, "%s.%d", fname, i); + status = file_status(fname2); + if (status == FN_NOENT) + break; + } + if (i == 10000) { + log_warn(LD_BUG, "Unable to parse state in \"%s\"; too many saved bad " + "state files to move aside. Discarding the old state file.", + fname); + unlink(fname); + } else { + log_warn(LD_BUG, "Unable to parse state in \"%s\". Moving it aside " + "to \"%s\". This could be a bug in Tor; please tell " + "the developers.", fname, fname2); + rename(fname, fname2); + } + tor_free(fname2); + tor_free(contents); + config_free(&state_format, new_state); + + new_state = tor_malloc_zero(sizeof(or_state_t)); + new_state->_magic = OR_STATE_MAGIC; + config_init(&state_format, new_state); + } else if (contents) { log_info(LD_GENERAL, "Loaded state from \"%s\"", fname); - else + } else { log_info(LD_GENERAL, "Initialized state"); + } or_state_set(new_state); new_state = NULL; if (!contents) { global_state->dirty = 1; or_state_save(); } - r = 0; + done: - if (errmsg) { - log_warn(LD_GENERAL, "%s", errmsg); - tor_free(errmsg); - } tor_free(fname); tor_free(contents); if (new_state) |