diff options
author | teor <teor2345@gmail.com> | 2014-10-19 17:48:07 +1100 |
---|---|---|
committer | teor <teor2345@gmail.com> | 2014-11-08 20:31:20 +1100 |
commit | fd7e9e9030cee9d8e863cea3f3f90226ae66fdfe (patch) | |
tree | a9ca33e658ff76b7a4bf4a7d5f9dd3a4936da575 /src/common | |
parent | ce7fd6e160e2e3acb824b29e29afe15cd5e7bf4f (diff) | |
download | tor-fd7e9e9030cee9d8e863cea3f3f90226ae66fdfe.tar.gz tor-fd7e9e9030cee9d8e863cea3f3f90226ae66fdfe.zip |
Stop failing when key files are zero-length
Instead, generate new keys, and overwrite the empty key files.
Adds FN_EMPTY to file_status_t and file_status.
Fixes bug 13111.
Related changes due to review of FN_FILE usage:
Stop generating a fresh .old RSA key file when the .old file is missing.
Avoid overwriting .old key files with empty key files.
Skip loading zero-length extra info store, router store, stats, state,
and key files.
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/compat.c | 1 | ||||
-rw-r--r-- | src/common/util.c | 30 | ||||
-rw-r--r-- | src/common/util.h | 2 |
3 files changed, 23 insertions, 10 deletions
diff --git a/src/common/compat.c b/src/common/compat.c index e4758aaf88..b28790f0e4 100644 --- a/src/common/compat.c +++ b/src/common/compat.c @@ -823,6 +823,7 @@ replace_file(const char *from, const char *to) case FN_NOENT: break; case FN_FILE: + case FN_EMPTY: if (unlink(to)) return -1; break; case FN_ERROR: diff --git a/src/common/util.c b/src/common/util.c index e850b14a16..1c35338eef 100644 --- a/src/common/util.c +++ b/src/common/util.c @@ -1888,10 +1888,15 @@ clean_name_for_stat(char *name) #endif } -/** Return FN_ERROR if filename can't be read, or is NULL or zero-length, - * FN_NOENT if it doesn't - * exist, FN_FILE if it is a regular file, or FN_DIR if it's a - * directory. On FN_ERROR, sets errno. */ +/** Return: + * FN_ERROR if filename can't be read, is NULL, or is zero-length, + * FN_NOENT if it doesn't exist, + * FN_FILE if it is a non-empty regular file, or a FIFO on unix-like systems, + * FN_EMPTY for zero-byte regular files, + * FN_DIR if it's a directory, and + * FN_ERROR for any other file type. + * On FN_ERROR and FN_NOENT, sets errno. (errno is not set when FN_ERROR + * is returned due to an unhandled file type.) */ file_status_t file_status(const char *fname) { @@ -1912,16 +1917,23 @@ file_status(const char *fname) } return FN_ERROR; } - if (st.st_mode & S_IFDIR) + if (st.st_mode & S_IFDIR) { return FN_DIR; - else if (st.st_mode & S_IFREG) - return FN_FILE; + } else if (st.st_mode & S_IFREG) { + if (st.st_size > 0) { + return FN_FILE; + } else if (st.st_size == 0) { + return FN_EMPTY; + } else { + return FN_ERROR; + } #ifndef _WIN32 - else if (st.st_mode & S_IFIFO) + } else if (st.st_mode & S_IFIFO) { return FN_FILE; #endif - else + } else { return FN_ERROR; + } } /** Check whether <b>dirname</b> exists and is private. If yes return 0. If diff --git a/src/common/util.h b/src/common/util.h index d7feb6e925..c5471ff9f2 100644 --- a/src/common/util.h +++ b/src/common/util.h @@ -334,7 +334,7 @@ enum stream_status get_string_from_pipe(FILE *stream, char *buf, size_t count); /** Return values from file_status(); see that function's documentation * for details. */ -typedef enum { FN_ERROR, FN_NOENT, FN_FILE, FN_DIR } file_status_t; +typedef enum { FN_ERROR, FN_NOENT, FN_FILE, FN_DIR, FN_EMPTY } file_status_t; file_status_t file_status(const char *filename); /** Possible behaviors for check_private_dir() on encountering a nonexistent |