Jelajahi Sumber

Follow symlinks in repo

Jakob Borg 12 tahun lalu
induk
melakukan
251b109d14
3 mengubah file dengan 46 tambahan dan 17 penghapusan
  1. 5 2
      README.md
  2. 14 14
      main.go
  3. 27 1
      walk.go

+ 5 - 2
README.md

@@ -46,9 +46,10 @@ The following features are _currently implemented and working_:
  * Handling of deleted files. Deletes can be propagated or ignored per
    client.
 
-The following features are _not yet implemented but planned_:
+ * Synchronizing multiple unrelated directory tries by following
+   symlinks directly below the repository level.
 
- * Syncing multiple directories from the same syncthing instance.
+The following features are _not yet implemented but planned_:
 
  * Change detection by listening to file system notifications instead of
    periodic scanning.
@@ -58,6 +59,8 @@ The following features are _not yet implemented but planned_:
 The following features are _not implemented but may be implemented_ in
 the future:
 
+ * Syncing multiple directories from the same syncthing instance.
+
  * Automatic remote node discovery using a DHT. This is not technically
    very difficult but requires one or more globally reachable root
    nodes. This is open for discussion -- perhaps we can piggyback on an

+ 14 - 14
main.go

@@ -34,7 +34,7 @@ Options:
   --ro             Local repository is read only
   --scan-intv <s>  Repository scan interval, in seconds [default: 60]
   --conn-intv <s>  Node reconnect interval, in seconds [default: 15]
-  --no-stats       Don't print transfer statistics
+  --no-symlinks    Don't follow first level symlinks in the repo
 
 Help Options:
   -h, --help       Show this help
@@ -54,17 +54,17 @@ var (
 
 // Options
 var (
-	confDir    = path.Join(getHomeDir(), confDirName)
-	addr       string
-	prof       string
-	readOnly   bool
-	scanIntv   int
-	connIntv   int
-	traceNet   bool
-	traceFile  bool
-	traceIdx   bool
-	printStats bool
-	doDelete   bool
+	confDir        = path.Join(getHomeDir(), confDirName)
+	addr           string
+	prof           string
+	readOnly       bool
+	scanIntv       int
+	connIntv       int
+	traceNet       bool
+	traceFile      bool
+	traceIdx       bool
+	doDelete       bool
+	followSymlinks bool
 )
 
 func main() {
@@ -95,7 +95,7 @@ func main() {
 	traceFile = arguments["--trace-file"].(bool)
 	traceNet = arguments["--trace-net"].(bool)
 	traceIdx = arguments["--trace-idx"].(bool)
-	printStats = !arguments["--no-stats"].(bool)
+	followSymlinks = !arguments["--no-symlinks"].(bool)
 
 	// Ensure that our home directory exists and that we have a certificate and key.
 
@@ -302,7 +302,7 @@ func connect(myID string, addr string, nodeAddrs map[string][]string, m *Model,
 }
 
 func updateLocalModel(m *Model) {
-	files := Walk(m.Dir(), m)
+	files := Walk(m.Dir(), m, followSymlinks)
 	m.ReplaceLocal(files)
 	saveIndex(m)
 }

+ 27 - 1
walk.go

@@ -89,13 +89,39 @@ func genWalker(base string, res *[]File, model *Model) filepath.WalkFunc {
 	}
 }
 
-func Walk(dir string, model *Model) []File {
+func Walk(dir string, model *Model, followSymlinks bool) []File {
 	var files []File
 	fn := genWalker(dir, &files, model)
 	err := filepath.Walk(dir, fn)
 	if err != nil {
 		warnln(err)
 	}
+
+	if followSymlinks {
+		d, err := os.Open(dir)
+		if err != nil {
+			warnln(err)
+			return files
+		}
+		fis, err := d.Readdir(-1)
+		if err != nil {
+			warnln(err)
+			return files
+		}
+		d.Close()
+		for _, fi := range fis {
+			if fi.Mode()&os.ModeSymlink != 0 {
+				if traceFile {
+					debugf("Following symlink %q", fi.Name())
+				}
+				err := filepath.Walk(path.Join(dir, fi.Name())+"/", fn)
+				if err != nil {
+					warnln(err)
+				}
+			}
+		}
+	}
+
 	return files
 }