summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2011-05-13 15:15:41 -0400
committerNick Mathewson <nickm@torproject.org>2011-05-15 20:20:29 -0400
commit3b6cbf253494303f612eeb09a6fbb30a7c15c7fa (patch)
treec7cc77c25edb68e869c78e47ed934fa1efebbc29
parentb147c01295deb8c09807fda3b5e4945edcfaf81a (diff)
downloadtor-3b6cbf253494303f612eeb09a6fbb30a7c15c7fa.tar.gz
tor-3b6cbf253494303f612eeb09a6fbb30a7c15c7fa.zip
Add a function to pull off the final component of a path
-rw-r--r--src/common/compat.c34
-rw-r--r--src/common/compat.h2
-rw-r--r--src/or/connection.c2
-rw-r--r--src/test/test_util.c30
4 files changed, 68 insertions, 0 deletions
diff --git a/src/common/compat.c b/src/common/compat.c
index ea7f9d7efc..3c5e9385e2 100644
--- a/src/common/compat.c
+++ b/src/common/compat.c
@@ -1467,6 +1467,40 @@ get_user_homedir(const char *username)
}
#endif
+/** Modify <b>fname</b> to contain the name of the directory */
+int
+get_parent_directory(char *fname)
+{
+ char *cp;
+ int at_end = 1;
+ tor_assert(fname);
+#ifdef MS_WINDOWS
+ /* If we start with, say, c:, then don't consider that the start of the path
+ */
+ if (fname[0] && fname[1] == ':') {
+ fname += 2;
+ }
+#endif
+ /* Now we want to remove the final character that */
+ cp = fname + strlen(fname);
+ at_end = 1;
+ while (--cp > fname) {
+ int is_sep = (*cp == '/'
+#ifdef MS_WINDOWS
+ || *cp == '\\'
+#endif
+ );
+ if (is_sep) {
+ *cp = '\0';
+ if (! at_end)
+ return 0;
+ } else {
+ at_end = 0;
+ }
+ }
+ return -1;
+}
+
/** Set *addr to the IP address (in dotted-quad notation) stored in c.
* Return 1 on success, 0 if c is badly formatted. (Like inet_aton(c,addr),
* but works on Windows and Solaris.)
diff --git a/src/common/compat.h b/src/common/compat.h
index af795ffba9..eff51ab30c 100644
--- a/src/common/compat.h
+++ b/src/common/compat.h
@@ -552,6 +552,8 @@ int switch_id(const char *user);
char *get_user_homedir(const char *username);
#endif
+int get_parent_directory(char *fname);
+
int spawn_func(void (*func)(void *), void *data);
void spawn_exit(void) ATTR_NORETURN;
diff --git a/src/or/connection.c b/src/or/connection.c
index 12e00e59bb..ab265df1af 100644
--- a/src/or/connection.c
+++ b/src/or/connection.c
@@ -967,6 +967,8 @@ connection_create_listener(const struct sockaddr *listensockaddr,
goto err;
}
if (get_options()->ControlSocketsGroupWritable) {
+ /* We need to use chmod; fchmod doesn't work on sockets on all
+ * platforms. */
if (chmod(address, 0660) < 0) {
log_warn(LD_FS,"Unable to make %s group-writable.", address);
tor_close_socket(s);
diff --git a/src/test/test_util.c b/src/test/test_util.c
index 0da45df499..23cd059cf7 100644
--- a/src/test/test_util.c
+++ b/src/test/test_util.c
@@ -1195,6 +1195,35 @@ test_util_listdir(void *ptr)
}
}
+static void
+test_util_parent_dir(void *ptr)
+{
+ char *cp;
+ (void)ptr;
+
+#define T(input,expect_ok,output) \
+ do { \
+ int ok; \
+ cp = tor_strdup(input); \
+ ok = get_parent_directory(cp); \
+ tt_int_op(ok, ==, expect_ok); \
+ if (ok==0) \
+ tt_str_op(cp, ==, output); \
+ tor_free(cp); \
+ } while (0);
+
+ T("/home/wombat/knish", 0, "/home/wombat");
+ T("/home/wombat/knish/", 0, "/home/wombat");
+ T("./home/wombat/knish/", 0, "./home/wombat");
+ T("./wombat", 0, ".");
+ T("", -1, "");
+ T("/", -1, "");
+ T("////", -1, "");
+
+ done:
+ tor_free(cp);
+}
+
#ifdef MS_WINDOWS
static void
test_util_load_win_lib(void *ptr)
@@ -1286,6 +1315,7 @@ struct testcase_t util_tests[] = {
UTIL_TEST(find_str_at_start_of_line, 0),
UTIL_TEST(asprintf, 0),
UTIL_TEST(listdir, 0),
+ UTIL_TEST(parent_dir, 0),
#ifdef MS_WINDOWS
UTIL_TEST(load_win_lib, 0),
#endif