commit 6d42c7b0e3902ad8b40b17ef096bb79d50ec56f1
Author: Yawning Angel <[email protected]>
Date:   Fri May 23 06:43:24 2014 +0000

    Implement MakeStateDir() instead of messing with the info structs.
    
    This fixes bug #12088.
---
 pt.go      |   35 ++++++++++-------------------------
 pt_test.go |   59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 69 insertions(+), 25 deletions(-)

diff --git a/pt.go b/pt.go
index 7f6c0a7..dba6701 100644
--- a/pt.go
+++ b/pt.go
@@ -322,20 +322,17 @@ func getManagedTransportVer() (string, error) {
        return "", versionError("no-version")
 }
 
-// Get the pluggable transport state location offered by Tor, and create it if
-// missing.  This function reads the enviornment variable
-// TOR_PT_STATE_LOCATION.
-func getStateLocation() (string, error) {
-       stateLocation, err := getenvRequired("TOR_PT_STATE_LOCATION")
+// Return the directory name in the TOR_PT_STATE_LOCATION environment variable,
+// creating it if it doesn't exist. Returns non-nil error if
+// TOR_PT_STATE_LOCATION is not set or if there is an error creating the
+// directory.
+func MakeStateDir() (string, error) {
+       dir, err := getenvRequired("TOR_PT_STATE_LOCATION")
        if err != nil {
                return "", err
        }
-       err = os.MkdirAll(stateLocation, 0700)
-       if err != nil {
-               return "", envError(fmt.Sprintf("error creating 
TOR_PT_STATE_LOCATION: %s", err))
-       }
-
-       return stateLocation, nil
+       err = os.MkdirAll(dir, 0700)
+       return dir, err
 }
 
 // Get the intersection of the method names offered by Tor and those in
@@ -353,10 +350,9 @@ func getClientTransports(star []string) ([]string, error) {
 }
 
 // This structure is returned by ClientSetup. It consists of a list of method
-// names and the state location.
+// names.
 type ClientInfo struct {
        MethodNames   []string
-       StateLocation string
 }
 
 // Check the client pluggable transports environment, emitting an error message
@@ -370,11 +366,6 @@ func ClientSetup(star []string) (info ClientInfo, err 
error) {
        }
        line("VERSION", ver)
 
-       info.StateLocation, err = getStateLocation()
-       if err != nil {
-               return
-       }
-
        info.MethodNames, err = getClientTransports(star)
        if err != nil {
                return
@@ -540,13 +531,12 @@ func readAuthCookieFile(filename string) ([]byte, error) {
 
 // This structure is returned by ServerSetup. It consists of a list of
 // Bindaddrs, an address for the ORPort, an address for the extended ORPort (if
-// any), an authentication cookie (if any), and the state location.
+// any), and an authentication cookie (if any).
 type ServerInfo struct {
        Bindaddrs      []Bindaddr
        OrAddr         *net.TCPAddr
        ExtendedOrAddr *net.TCPAddr
        AuthCookie     []byte
-       StateLocation  string
 }
 
 // Check the server pluggable transports environment, emitting an error message
@@ -561,11 +551,6 @@ func ServerSetup(star []string) (info ServerInfo, err 
error) {
        }
        line("VERSION", ver)
 
-       info.StateLocation, err = getStateLocation()
-       if err != nil {
-               return
-       }
-
        info.Bindaddrs, err = getServerBindaddrs(star)
        if err != nil {
                return
diff --git a/pt_test.go b/pt_test.go
index 5689405..b569352 100644
--- a/pt_test.go
+++ b/pt_test.go
@@ -8,6 +8,7 @@ import (
        "io/ioutil"
        "net"
        "os"
+       "path"
        "sort"
        "testing"
 )
@@ -738,6 +739,64 @@ func TestExtOrPortSetup(t *testing.T) {
        testExtOrPortSetupIndividual(t, addr, methodName)
 }
 
+func TestMakeStateDir(t *testing.T) {
+       os.Clearenv()
+
+       // TOR_PT_STATE_LOCATION not set.
+       _, err := MakeStateDir()
+       if err == nil {
+               t.Errorf("empty environment unexpectedly succeeded")
+       }
+
+       // Setup the scratch directory.
+       tempDir, err := ioutil.TempDir("", "testMakeStateDir")
+       if err != nil {
+               t.Fatalf("ioutil.TempDir failed: %s", err)
+       }
+       defer os.RemoveAll(tempDir)
+
+       goodTests := [...]string {
+               // Already existing directory.
+               tempDir,
+
+               // Nonexistent directory, parent exists.
+               path.Join(tempDir, "parentExists"),
+
+               // Nonexistent directory, parent doesn't exist.
+               path.Join(tempDir, "missingParent", "parentMissing"),
+       }
+       for _, test := range goodTests {
+               os.Setenv("TOR_PT_STATE_LOCATION", test)
+               dir, err := MakeStateDir()
+               if err != nil {
+                       t.Errorf("MakeStateDir unexpectedly failed: %s", err)
+               }
+               if dir != test {
+                       t.Errorf("MakeStateDir returned an unexpected path %s 
(expecting %s)", dir, test)
+               }
+       }
+
+       // Name already exists, but is an ordinary file.
+       tempFile := path.Join(tempDir, "file")
+       f, err := os.Create(tempFile)
+       if err != nil {
+               t.Fatalf("os.Create failed: %s", err)
+       }
+       defer f.Close()
+       os.Setenv("TOR_PT_STATE_LOCATION", tempFile)
+       _, err = MakeStateDir()
+       if err == nil {
+               t.Errorf("MakeStateDir with a file unexpectedly succeded")
+       }
+
+       // Directory name that cannot be created. (Subdir of a file)
+       os.Setenv("TOR_PT_STATE_LOCATION", path.Join(tempFile, "subDir"))
+       _, err = MakeStateDir()
+       if err == nil {
+               t.Errorf("MakeStateDir with a subdirectory of a file 
unexpectedly succeded")
+       }
+}
+
 func TestIsClient(t *testing.T) {
        os.Clearenv()
        if IsClient() {

_______________________________________________
tor-commits mailing list
[email protected]
https://lists.torproject.org/cgi-bin/mailman/listinfo/tor-commits

Reply via email to