Просмотр исходного кода

Make check_private_dir trimodal (check/create/ignore), not bimodal (create/ignore).

svn:r2733
Nick Mathewson 21 лет назад
Родитель
Сommit
180e0a9326
5 измененных файлов с 32 добавлено и 20 удалено
  1. 19 14
      src/common/util.c
  2. 2 1
      src/common/util.h
  3. 8 2
      src/or/config.c
  4. 1 1
      src/or/rendservice.c
  5. 2 2
      src/or/router.c

+ 19 - 14
src/common/util.c

@@ -701,9 +701,11 @@ file_status_t file_status(const char *fname)
 }
 
 /** Check whether dirname exists and is private.  If yes return 0.  If
- * it does not exist, and create is set, try to create it and return 0
- * on success.  Else return -1. */
-int check_private_dir(const char *dirname, int create)
+ * it does not exist, and check==CPD_CREATE is set, try to create it
+ * and return 0 on success. If it does not exist, and
+ * check==CPD_CHECK, and we think we can create it, return 0.  Else
+ * return -1. */
+int check_private_dir(const char *dirname, cpd_check_t check)
 {
   int r;
   struct stat st;
@@ -714,23 +716,26 @@ int check_private_dir(const char *dirname, int create)
           strerror(errno));
       return -1;
     }
-    if (!create) {
+    if (check == CPD_NONE) {
       log(LOG_WARN, "Directory %s does not exist.", dirname);
       return -1;
-    }
-    log(LOG_INFO, "Creating directory %s", dirname);
+    } else if (check == CPD_CREATE) {
+      log(LOG_INFO, "Creating directory %s", dirname);
 #ifdef MS_WINDOWS
-    r = mkdir(dirname);
+      r = mkdir(dirname);
 #else
-    r = mkdir(dirname, 0700);
+      r = mkdir(dirname, 0700);
 #endif
-    if (r) {
-      log(LOG_WARN, "Error creating directory %s: %s", dirname,
-          strerror(errno));
-      return -1;
-    } else {
-      return 0;
+      if (r) {
+        log(LOG_WARN, "Error creating directory %s: %s", dirname,
+            strerror(errno));
+        return -1;
+      }
     }
+
+    /* XXXX In the case where check==CPD_CHECK, we should look at the
+     * parent directory a little harder. */
+    return 0;
   }
   if (!(st.st_mode & S_IFDIR)) {
     log(LOG_WARN, "%s is not a directory", dirname);

+ 2 - 1
src/common/util.h

@@ -88,7 +88,8 @@ int read_all(int fd, char *buf, size_t count, int isSocket);
 typedef enum { FN_ERROR, FN_NOENT, FN_FILE, FN_DIR} file_status_t;
 file_status_t file_status(const char *filename);
 
-int check_private_dir(const char *dirname, int create);
+typedef enum { CPD_NONE, CPD_CREATE, CPD_CHECK } cpd_check_t;
+int check_private_dir(const char *dirname, cpd_check_t check);
 int write_str_to_file(const char *fname, const char *str, int bin);
 int write_bytes_to_file(const char *fname, const char *str, size_t len,
                         int bin);

+ 8 - 2
src/or/config.c

@@ -241,9 +241,8 @@ options_act(void) {
     }
   }
 
-/*XXX in options_validate, we should check if this is going to fail */
   /* Ensure data directory is private; create if possible. */
-  if (check_private_dir(options->DataDirectory, 1) != 0) {
+  if (check_private_dir(options->DataDirectory, CPD_CREATE) != 0) {
     log_fn(LOG_ERR, "Couldn't access/create private data directory %s",
            options->DataDirectory);
     return -1;
@@ -1014,6 +1013,13 @@ options_validate(or_options_t *options)
   if (normalize_log_options(options))
     return -1;
 
+
+  if (options->DataDirectory &&
+      check_private_dir(options->DataDirectory, CPD_CHECK != 0)) {
+    log_fn(LOG_WARN, "Can't create directory %s", options->DataDirectory);
+    result = -1;
+  }
+
   /* Special case if no options are given. */
   if (!options->Logs) {
     options->Logs = config_line_prepend(NULL, "Log", "notice-err stdout");

+ 1 - 1
src/or/rendservice.c

@@ -295,7 +295,7 @@ int rend_service_load_keys(void)
     log_fn(LOG_INFO, "Loading hidden-service keys from '%s'", s->directory);
 
     /* Check/create directory */
-    if (check_private_dir(s->directory, 1) < 0)
+    if (check_private_dir(s->directory, CPD_CREATE) < 0)
       return -1;
 
     /* Load key */

+ 2 - 2
src/or/router.c

@@ -259,12 +259,12 @@ int init_keys(void) {
   }
   /* Make sure DataDirectory exists, and is private. */
   datadir = options->DataDirectory;
-  if (check_private_dir(datadir, 1)) {
+  if (check_private_dir(datadir, CPD_CREATE)) {
     return -1;
   }
   /* Check the key directory. */
   tor_snprintf(keydir,sizeof(keydir),"%s/keys", datadir);
-  if (check_private_dir(keydir, 1)) {
+  if (check_private_dir(keydir, CPD_CREATE)) {
     return -1;
   }
   cp = keydir + strlen(keydir); /* End of string. */