aboutsummaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorteor <teor2345@gmail.com>2014-10-19 17:48:07 +1100
committerteor <teor2345@gmail.com>2014-11-08 20:31:20 +1100
commitfd7e9e9030cee9d8e863cea3f3f90226ae66fdfe (patch)
treea9ca33e658ff76b7a4bf4a7d5f9dd3a4936da575 /src/common
parentce7fd6e160e2e3acb824b29e29afe15cd5e7bf4f (diff)
downloadtor-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.c1
-rw-r--r--src/common/util.c30
-rw-r--r--src/common/util.h2
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