diff --git a/README.md b/README.md index 6568a168a..70f1ce105 100644 --- a/README.md +++ b/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 diff --git a/main.go b/main.go index 74703e1db..783698a7a 100644 --- a/main.go +++ b/main.go @@ -34,7 +34,7 @@ Options: --ro Local repository is read only --scan-intv Repository scan interval, in seconds [default: 60] --conn-intv 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) } diff --git a/walk.go b/walk.go index 4e50b4973..65dc460c1 100644 --- a/walk.go +++ b/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 }